You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL如何使用Lag/Lead窗口函数合并同值连续行的起止日期

问题说明

现有表共4个字段:ID、STARTDATE、ENDDATE、BADGE,需实现行合并逻辑:仅合并ID、BADGE取值完全相同的连续排列行,合并后取组内最早的STARTDATE为开始日期、最晚的ENDDATE为结束日期。

  • 输入示例:
    输入示例
  • 期望输出示例:
    期望输出
原有尝试写法的问题

已提交的窗口函数写法存在两处核心错误,导致结果不符合预期:

  • 分区/判断维度遗漏BADGE字段,仅以ID作为分区依据,无法满足ID+BADGE双字段同时匹配才合并的规则
  • 未正确生成连续同值行的唯一分组标识,直接取上一行STARTDATE的逻辑无法适配连续3行及以上同值的场景,会出现分组错位
可落地实现方案

核心逻辑:先通过窗口函数为每段连续的ID+BADGE同值行生成独立的分组标记,再基于该标记聚合即可。

通用SQL写法(适配绝大多数支持窗口函数的数据库:MySQL8.0+、PostgreSQL、SQL Server、Hive等)

WITH temp_group AS (
    SELECT
        ID,
        BADGE,
        STARTDATE,
        ENDDATE,
        -- 生成连续分组标记:当前行BADGE和同ID下上一行不同时,标记值累加1
        SUM(
            CASE
                WHEN LAG(BADGE) OVER(PARTITION BY ID ORDER BY STARTDATE) = BADGE THEN 0
                ELSE 1
            END
        ) OVER(PARTITION BY ID ORDER BY STARTDATE ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS group_tag
    FROM myTable
)
SELECT
    ID,
    MIN(STARTDATE) AS STARTDATE,
    MAX(ENDDATE) AS ENDDATE,
    BADGE
FROM temp_group
GROUP BY ID, BADGE, group_tag
ORDER BY ID, STARTDATE;

简化写法(适配Snowflake、Databricks等支持CONDITIONAL_CHANGE_EVENT函数的引擎)

SELECT
    ID,
    MIN(STARTDATE) AS STARTDATE,
    MAX(ENDDATE) AS ENDDATE,
    BADGE
FROM myTable
GROUP BY
    ID,
    BADGE,
    CONDITIONAL_CHANGE_EVENT(BADGE) OVER(PARTITION BY ID ORDER BY STARTDATE)
ORDER BY ID, STARTDATE;

内容的提问来源于stack exchange,提问作者Bilal Shafqat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 06:18:22