差距和岛屿 - 如何按 ID 对每组连续行求和
Posted
技术标签:
【中文标题】差距和岛屿 - 如何按 ID 对每组连续行求和【英文标题】:Gaps and Islands - How to Sum Each Group of Consecutive Rows by ID 【发布时间】:2020-08-30 21:34:34 【问题描述】:以下是我当前的 SQL 代码和输出。我只需要获得 CD 等于 STG(以黄色突出显示)的连续(或单)行的 EFF_DAYS 的总和。
SELECT ROW_NUMBER() OVER (PARTITION BY ID ORDER BY TMSP, EFF_DT) RN,
Z2.*
FROM (
SELECT CASE WHEN (LAG_CD IS NULL OR LAG_CD NOT IN ('STG')) AND CD IN ('STG')
THEN RANK() OVER (PARTITION BY ID ORDER BY TMSP, EFF_DT)
WHEN CD = LAG_CD AND CD IN ('STG')
THEN RANK() OVER (PARTITION BY ID ORDER BY TMSP, EFF_DT)
WHEN CD = LAG_CD AND CD != LEAD_CD
THEN RANK() OVER (PARTITION BY ID ORDER BY TMSP, EFF_DT)
END AS CASES,
Z.* FROM (
SELECT ID,
LAG(CD) OVER (PARTITION BY ID ORDER BY TMSP, EFF_DT) AS LAG_CD,
LEAD(CD) OVER (PARTITION BY ID ORDER BY TMSP, EFF_DT) AS LEAD_CD,
CD,
TMSP,
EFF_DT,
END_EFF_DT,
DATEDIFF(day, EFF_DT, END_EFF_DT) AS EFF_DAYS
FROM #POSTCHG_ROWS
WHERE ID IN ('ABC123', 'XYZ789')
) Z
) Z2 ORDER BY TMSP, EFF_DT
我尝试了各种行号和排名的东西,但我似乎无法让 CASES 列正确。我花了几个小时研究其他 gap-island sql 解决方案,但没有遇到下面的确切情况。
理想情况下,我的 CASES 列会像下面这样输出,这样我就可以 GROUP BY CASES、ID、连续行块的起始 TMSP,然后计算:SUM(EFF_DAYS)。
以下是我的目标输出:
【问题讨论】:
以消费格式发布数据,而不是图像。最好是 DDL 和 DML 语句,因为我们可以复制和粘贴然后运行代码,但在其他方面很好地呈现表格格式text
。
如何将其呈现为格式化文本?在代码块中?
【参考方案1】:
您只对一系列相邻的“CTG”行感兴趣。我认为最简单的方法是对非“STG”值的窗口计数来定义组,然后进行过滤和聚合:
select
id,
min(tmsp) tmsp,
min(eff_dt) eff_dt,
sum(datediff(day, eff_dt, end_eff_dt)) sum_eff_days
from (
select
p.*
sum(case when cd = 'STG' then 0 else 1 end)
over(partition by id order by tmsp) grp
from #postchg_rows p
) p
where cd = 'STG'
group by id, grp
【讨论】:
选择 p.* 后缺少逗号,但除此之外这对我有用。以上是关于差距和岛屿 - 如何按 ID 对每组连续行求和的主要内容,如果未能解决你的问题,请参考以下文章
如何创建一个变量,该变量是给定时间范围内连续行的总和并按 id
差距和岛屿 - 使用 Postgresql 获取某个日期范围内的失业日期列表