• 计算分组后组内最大值


    【问题】

    sql maximum record per group question

    1. CREATE
    2. TABLEDBO.TEST
    3. (
    4. IDINT,RECTYPEINT,SEQINT,MAX0INT,MAX1INT,MAX2INT)
    5. INSERT
    6. INTOdbo.TEST
    7. SELECT
    8. 1,1,1,3,2,3
    9. UNION
    10. ALL
    11. SELECT
    12. 1,2,2,3,2,3
    13. UNION
    14. ALL
    15. SELECT
    16. 1,2,3,3,2,3
    17. UNION
    18. ALL
    19. SELECT
    20. 1,1,2,3,2,3
    21. --SELECT * FROM dbo.TEST
    22. how
    23. tofindMAXseqforeach IDandRectype
    24. My result should be
    25. MAX0
    26. ismaximumofseqgroupbyID
    27. MAX1
    28. ismaximumofseqgroupbyIDwhererectype=1
    29. MAX2 id maximum
    30. ofseqgroupbyIDwhererectype=2
    1. ID Rectype SEQ MAX0 MAX1 MAX2
    2. 1 1 1 3 2 3
    3. 1 2 2 3 2 3
    4. 1 2 3 3 2 3
    5. 1 1 2 3 2 3

    别人的回答:

    1. CREATETABLEDBO.TEST
    2. (
    3. ID INT,
    4. RECTYPE INT,
    5. SEQ INT,
    6. MAX0 INT,
    7. MAX1 INT,
    8. MAX2 INT
    9. )
    10. INSERTINTOdbo.TEST
    11. SELECT1,1,1,NULL,NULL,NULL
    12. UNIONALL
    13. SELECT1,2,2,NULL,NULL,NULL
    14. UNIONALL
    15. SELECT1,2,3,NULL,NULL,NULL
    16. UNIONALL
    17. SELECT1,1,2,NULL,NULL,NULL
    18. --select * from test
    19. ;WITHmycte
    20. AS(SELECTID,
    21. RECTYPE,
    22. Max(seq)
    23. OVER(partition BYID)m0,
    24. CASE
    25. WHENrectype =1THENMax(SEQ)OVER(PARTITION BYid,rectype)
    26. ELSENULL
    27. ENDm1,
    28. CASE
    29. WHENrectype =2THENMax(SEQ)OVER(PARTITION BYid,rectype)
    30. ELSENULL
    31. ENDm2
    32. FROMdbo.TEST)
    33. SELECTID,
    34. RECTYPE,
    35. M0,
    36. Max(m1)OVER(partition BYID)m1,
    37. Max(m2)
    38. OVER(partition BYID)m2
    39. FROMmycte
    40. droptabletest

    【回答】

    这是个比较典型的组内计算,解决思路很清晰:

    1. 将数据按 ID 分成多个组,每个组是一个 ID 的全部数据。

    2. 进行组内运算,求得本组内 SEQ 的最大值,赋给 MAX0。

    3. 组内运算,过滤出本组内 Rectype=1 的记录,再求 SEQ 的最大值,赋给 MAX1。

    4. 组内运算,过滤出本组内 Rectype=2 的记录,再求 SEQ 的最大值,赋给 MAX2。

    上述思路虽然清晰,但用 SQL 却很难表达组内运算,只能转化成 N 个窗口函数嵌套多级关联。这样的代码复杂难懂,下次遇到类似的问题恐怕还是不会写。如果数据量不是非常大时,建议采用 SPL 来辅助。SPL 可以方便地表达组内运算,可以很容易解决你的问题,代码如下:

    A
    1=tbData.group(ID)
    2=A1.run(~.run(MAX0=A1.~.max(SEQ)))
    3=A1.run(~.run(MAX1= A1.~.select(Rectype==1).max(SEQ)))
    4=A1. run(~.run(MAX2= A1.~.select(Rectype==2).max(SEQ)))

    代码中的“~”就表示每个分组,类似于循环变量。另外,步骤 2,3,4 可以合为一步:

    1. =A1.run(~.run(MAX0=A1.~.max(SEQ)),
    2. ~.run(MAX1=A1.~.select(Rectype==1).max(SEQ)),
    3. ~.run(MAX2=A1.~.select(Rectype==2).max(SEQ)) )

    上述计算结果是 ResultSet 类型,和 JAVA 或报表都很容易集成,可以参看:

    集算器简化 SQL 式计算之组内运算

     

  • 相关阅读:
    gpio模拟spi读写寄存器示例代码
    【字符串的copy Objective-C语言】
    Spring Boot Security自带功能齐全的HttpFirewall防火墙
    【数据结构趣味多】时间复杂度和空间复杂度
    最新Win11安装安卓子系统详细教程
    数据治理是一个怎样的体系化的过程?_光点科技
    计算机网络性能指标
    解密分布式事务:CAP理论、BASE理论、两阶段提交(2PC)、三阶段提交(3PC)、补偿事务(TCC)、MQ事务消息、最大努力通知
    maven环境配置
    前端开发网站推荐
  • 原文地址:https://blog.csdn.net/raqsoft/article/details/126927034