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

如何合并同一A_ID下时间无间断的起止日期?已尝试多种方法未成功

合并同一A_ID下连续时间段的SQL解决方案

嘿,我明白你要解决的问题——把同一A_ID下时间无缝衔接的起止日期合并成一个连续区间对吧?这是典型的区间合并场景,咱们一步步来搞定它。

首先先确认你的测试数据:

CREATE TABLE #t ( A_ID VARCHAR(100), BDate VARCHAR(100), CDate VARCHAR(100) )
INSERT INTO #t (A_ID, BDate, CDate) 
VALUES ('1000','2017/12/01','2017/12/31'), 
       ('1000','2018/01/01','2018/03/31'), 
       ('1000','2018/05/01','2018/05/31')

你的思路用窗口函数是对的,但需要进一步区分哪些行属于同一个连续区间。这里我们可以用LAG函数对比当前行的起始日期和上一行的结束日期,判断是否连续,再生成分组标识来聚合。

完整解决方案代码

WITH date_converted AS (
    -- 先把字符串日期转换成DATE类型,方便日期运算
    SELECT 
        A_ID,
        CONVERT(DATE, BDate, 111) AS BDate,
        CONVERT(DATE, CDate, 111) AS CDate
    FROM #t
),
interval_groups AS (
    -- 标记每个连续区间的起始点,生成分组ID
    SELECT 
        A_ID,
        BDate,
        CDate,
        -- 如果当前行的BDate是上一行CDate的下一天,属于同一组;否则新组
        SUM(CASE 
                WHEN LAG(CDate) OVER (PARTITION BY A_ID ORDER BY BDate) = DATEADD(DAY, -1, BDate) 
                THEN 0 
                ELSE 1 
            END) OVER (PARTITION BY A_ID ORDER BY BDate) AS GroupID
    FROM date_converted
)
-- 按A_ID和GroupID聚合,取每个组的最小起始日期和最大结束日期
SELECT 
    A_ID,
    CONVERT(VARCHAR(100), MIN(BDate), 111) AS Merged_BDate,
    CONVERT(VARCHAR(100), MAX(CDate), 111) AS Merged_CDate
FROM interval_groups
GROUP BY A_ID, GroupID
ORDER BY A_ID, Merged_BDate;

代码解释

  1. date_converted CTE:把VARCHAR类型的日期转换成DATE类型,这样才能正确进行日期加减和比较操作(建议实际业务表直接用DATE类型存日期,避免字符串格式问题)。
  2. interval_groups CTE:使用LAG(CDate) OVER (PARTITION BY A_ID ORDER BY BDate)获取同一A_ID下上一行的结束日期,判断当前行的起始日期是否是上一行结束日期的下一天——如果是,说明两个区间连续,属于同一组;否则是新的组。用SUM累加标记值生成唯一的GroupID。
  3. 最后聚合步骤:按A_ID和GroupID分组,取每个组的最小起始日期和最大结束日期,就是合并后的连续区间。

预期输出

A_IDMerged_BDateMerged_CDate
10002017/12/012018/03/31
10002018/05/012018/05/31

这样就完美合并了连续的时间段,不连续的区间也能保持独立~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 11:10:44