【问题标题】:Can this query be solved using something besides 2 CTEs?可以使用 2 个 CTE 之外的其他方法来解决此查询吗?
【发布时间】:2019-03-21 04:02:11
【问题描述】:

我正在使用随机生成的虚构名称和数据对名为 CLAIMS 的虚构保险蛤蜊表编写查询。

名为 PRIMARY_DX 的列中有 5 个不同的类别: 酗酒、焦虑症、抑郁症、精神病、物质使用障碍

其他主要列是 PATIENT_ID 和 CLAIM_PAID_AMT

我想总结每个 PATIENT 每个 PRIMARY_DX 的 CLAIM_PAID_AMT 并仅列出每个 PRIMARY_DX 总和最高的前 5 名患者

我能想到的唯一方法是使用两个通用表表达式,在 CTE1 中,我按 PRIMARY_DX 和 PATIENT_ID 进行分区,并对每个 PATIENT 的 CLAIM_PAID_AMT 求和。

然后在 CTE2 中,我在 CTE1 上使用 ROW_NUMBER 函数,按 PRIMARY_DX 分区并按 TotalClaims DESC 排序,并从每个 PRIMARY_DX 中选择前 5 个。

我写 SQL 不到 2 年,想知道这是否可以在一个 CTE 中完成,或者可能通过某种形式的交叉应用来完成?

我将我的代码和下面的输出包括在内。

;WITH CTE1 AS
(
select PRIMARY_DX, PATIENT_ID, TotalClaims = SUM(CLAIM_PAID_AMT)
OVER (PARTITION BY PRIMARY_DX, PATIENT_ID ORDER BY PATIENT_ID, CLAIM_PAID_AMT DESC)
from claims
)
, 
CTE2 AS
(SELECT *, RowCounter = ROW_NUMBER() OVER (PARTITION BY PRIMARY_DX ORDER BY TotalClaims DESC) FROM CTE1)
select CTE2.PRIMARY_DX, CTE2.TotalClaims from CTE2
where RowCounter <= 5
order by CTE2.PRIMARY_DX, CTE2.TotalClaims DESC

酗酒 3737.51 乔·史密斯

酗酒 3282.07 苏西家庭主妇

酗酒 3207.72 Joey Strummer

酗酒 3040.52 生锈的指甲锉

酗酒 2997.02 大本钟

焦虑症 3291.14 诺曼猪圈

焦虑症 3113.05 比利·鲍勃

焦虑症 3101.13 雷切尔南极洲

焦虑症 3058.52 约翰·约翰

焦虑症 3021.98 凯西欧罗巴

大萧条 3466.14 Freda Beagallly

大萧条 3279.25 罗恩·杰雷米兹

大萧条 3140.43 莎朗·沙罗纳兹

大萧条 3119.26 艾莉凯特

大萧条 3118.54 Biff Biffstoferson

精神病 3098.13 詹姆斯大富翁

精神病 2991.23 Leon 错误地

精神病 2857.69 Lucie Ratched-McMurphy

精神病 2678.88 比利·比比茨

精神病 2602.24 Sam Zypperzsky

物质使用障碍 3435.27 Donald Duckaronawitz

物质使用障碍 3300.33 米老鼠夹

物质使用障碍 3285.41 Hector Heathercoatz

物质使用障碍 3179 Erin GoBragh

物质使用障碍 3147.09 Bono Edgerstein

【问题讨论】:

    标签: tsql common-table-expression window-functions


    【解决方案1】:

    您应该只需要一个子查询或 CTE,因为您可以在 ROW_NUMBER() 中使用聚合。

    这是一种使用子查询的方法:

    SELECT *
    FROM (
        SELECT PRIMARY_DX, PATIENT, SUM(CLAIM_PAID_AMT) AS CLAIM_PAID_AMT,
            ROW_NUMBER() OVER (PARTITION BY PRIMARY_DX ORDER BY SUM(CLAIM_PAID_AMT) DESC) AS RowId
        FROM Claims GROUP BY PRIMARY_DX, PATIENT
    ) T
    WHERE RowId <= 5
    

    如果您更喜欢 CTE:

    ;WITH CTE AS (
        SELECT PRIMARY_DX, PATIENT, SUM(CLAIM_PAID_AMT) AS CLAIM_PAID_AMT,
            ROW_NUMBER() OVER (PARTITION BY PRIMARY_DX ORDER BY SUM(CLAIM_PAID_AMT) DESC) AS RowId
        FROM Claims GROUP BY PRIMARY_DX, PATIENT
    ) SELECT * FROM CTE WHERE RowId <= 5
    

    【讨论】:

      猜你喜欢
      • 2016-12-23
      • 1970-01-01
      • 2017-09-09
      • 1970-01-01
      • 2014-12-02
      • 2016-10-14
      • 2018-03-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多