能否使用 2 个 CTE 以外的方法解决此查询?

Can this query be solved using something besides 2 CTEs?

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

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

其他主要列是 PATIENT_ID 和 CLAIM_PAID_AMT

我想总结每个 PRIMARY_DX 每个患者的 CLAIM_PAID_AMT 并且只列出每个 PRIMARY_DX

总和最高的前 5 名患者

我能想到的唯一方法是使用两个常见的 Table 表达式,在 CTE1 中,我按 PRIMARY_DX 和 PATIENT_ID 进行分区,并对 CLAIM_PAID_AMT 求和对于每位患者。

然后在 CTE2 中,我在 CTE1 上使用 ROW_NUMBER 函数,按 PRIMARY_DX 进行分区并按 TotalClaims DESC 和 select 每个 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 Norman Pigsty

焦虑症 3113.05 比利鲍勃

焦虑症 3101.13 雷切尔南极洲

焦虑症 3058.52 John John

焦虑症 3021.98 Kathy Europa

抑郁症 3466.14 Freda Beagallly

抑郁症 3279.25 Ron Jeremize

抑郁症 3140.43 Sharon Sharonaz

抑郁症 3119.26 Allie Kat

抑郁症 3118.54 Biff Biffstoferson

精神病 3098.13 詹姆斯大富翁

精神病 2991.23 里昂错

精神病 2857.69 Lucie Ratched-McMurphy

精神病 2678.88 Billy Bibbitz

精神病 2602.24 Sam Zypperzsky

物质使用障碍 3435.27 Donald Duckaronawitz

物质使用障碍 3300.33 米奇捕鼠器

物质使用障碍 3285.41 Hector Heathercoatz

物质使用障碍 3179 Erin GoBragh

物质使用障碍 3147.09 Bono Edgerstein

您应该只需要一个子查询或 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