• 计算分组后组内最大值


    【问题】

    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 式计算之组内运算

     

  • 相关阅读:
    趣学python编程 (五、常用IDE环境推荐)
    挺后悔,我敷衍地回答了“程序员如何提升抽象思维“
    制作404页面的注意事项
    【ES】笔记-Map介绍与API
    如何理解BFC
    java-php-net-python-东软健身会员网站计算机毕业设计程序
    STM32 4位数码管和74HC595
    electron学习笔记
    html静态网站简单的学生网页作业源码 基于游戏网站设计与实现共计10个页面 (仿地下城与勇士游戏网页)
    Python爬虫详解:原理、常用库与实战案例
  • 原文地址:https://blog.csdn.net/raqsoft/article/details/126927034