如何使用窗口函数获取连续同组内的最小日期值
问题解决方法
你原有写法的问题在于PARTITION BY TYPE会将全表所有TYPE=LF的行归入同一个分区,无法识别被FI行打断的多段独立LF连续序列,这属于SQL中典型的连续序列(岛屿)识别场景,可以通过「断点标记+累计求和分组」的逻辑实现:
实现步骤
- 第一步:新增断点标记:每次遇到TYPE≠LF的行时标记为1,LF行标记为0,用来识别连续序列的分割点
- 第二步:对断点标记按ID分区、DATE升序做累计求和,此时同一段连续LF行的累计求和结果会完全相同,相当于给每段连续LF分配了唯一的分组ID
- 第三步:对LF行,按ID+分组ID分区取最小DATE,就是所需的NEW_DATE值
完整SQL代码
WITH temp AS ( SELECT *, -- 标记断点:非LF行记1,LF行记0 SUM(CASE WHEN TYPE <> 'LF' THEN 1 ELSE 0 END) OVER (PARTITION BY ID ORDER BY DATE) AS group_id FROM customer ) SELECT DATE, ID, TYPE, CASE WHEN TYPE = 'LF' THEN MIN(DATE) OVER (PARTITION BY ID, group_id) ELSE NULL END AS NEW_DATE FROM temp ORDER BY DATE
逻辑说明
- 样例数据中计算出的group_id依次为:1(第一行FI)、1(第一个LF序列的两行)、2(第二行FI)、2(第二个LF序列的一行)
- 同group_id下的LF行自然属于同一段连续序列,取MIN(DATE)即可得到对应段的最小日期,完全符合需求
- 代码中加入了
PARTITION BY ID,可适配多ID的业务场景,若表中只有单ID可酌情删除
内容的提问来源于stack exchange,提问作者Ishaan
相关产品推荐
相关产品推荐

