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

如何让ROW_NUMBER在分区内相同值的间断处重新开始计数?

实现连续相同PackedStr记录的分组统计

首先准备测试数据:

CREATE TABLE #t (PackedStr VARCHAR(100), Ident INT, BeginDate DATE, EndDate DATE);
INSERT #t
VALUES ('A,B,C,D,E', 86, '2019-03-18', '2019-03-27')
     , ('A,B,C,D,E', 87, '2019-03-28', '2019-04-09')
     , ('A,B,C,D,E,F,G', 88, '2019-04-10', '2019-04-15')
     , ('A,B,C,D,E', 89, '2019-04-16', '2019-04-24')
     , ('A,B,C,D,E', 90, '2019-04-25', '2019-05-14');

现有问题

原查询直接按PackedStr分区,导致非连续的相同PackedStr被归为同一组,结果不符合预期:

SELECT *
     , ROW_NUMBER() OVER (PARTITION BY [PackedStr] ORDER BY [Ident]) RowNumber
     , MIN( BeginDate ) OVER (PARTITION BY [PackedStr] ORDER BY [Ident]) FirstDate
     , MAX( EndDate ) OVER (PARTITION BY [PackedStr] ORDER BY [Ident] DESC) LastDate
FROM [#t]
ORDER BY [Ident];

当前结果

PackedStrIdentBeginDateEndDateRowNumberFirstDateLastDate
A,B,C,D,E862019-03-182019-03-2712019-03-182019-05-14
A,B,C,D,E872019-03-282019-04-0922019-03-182019-05-14
A,B,C,D,E,F,G882019-04-102019-04-1512019-04-102019-04-15
A,B,C,D,E892019-04-162019-04-2432019-03-182019-05-14
A,B,C,D,E902019-04-252019-05-1442019-03-182019-05-14

期望结果

PackedStrIdentBeginDateEndDateRowNumberFirstDateLastDate
A,B,C,D,E862019-03-182019-03-2712019-03-182019-04-09
A,B,C,D,E872019-03-282019-04-0922019-03-182019-04-09
A,B,C,D,E,F,G882019-04-102019-04-1512019-04-102019-04-15
A,B,C,D,E892019-04-162019-04-2412019-04-162019-05-14
A,B,C,D,E902019-04-252019-05-1422019-04-162019-05-14

解决方案

核心思路是用LAG()函数判断当前行的PackedStr与上一行是否相同,生成分组标识,再基于这个标识进行分区计算:

WITH GroupedData AS (
    SELECT 
        *,
        -- 当前行PackedStr与上一行不同时,生成新分组标记
        SUM(CASE WHEN LAG(PackedStr) OVER (ORDER BY Ident) = PackedStr THEN 0 ELSE 1 END) 
            OVER (ORDER BY Ident) AS GroupID
    FROM #t
)
SELECT 
    PackedStr,
    Ident,
    BeginDate,
    EndDate,
    ROW_NUMBER() OVER (PARTITION BY GroupID ORDER BY Ident) AS RowNumber,
    MIN(BeginDate) OVER (PARTITION BY GroupID) AS FirstDate,
    MAX(EndDate) OVER (PARTITION BY GroupID) AS LastDate
FROM GroupedData
ORDER BY Ident;

说明

  1. 生成GroupID:通过LAG(PackedStr) OVER (ORDER BY Ident)获取上一行的PackedStr,若与当前行不同则累加1,确保连续相同的PackedStr被分配到同一个分组ID。
  2. 基于GroupID计算字段:以GroupID作为分区键,计算每个连续分组内的行号、最早开始日期和最晚结束日期,完全匹配期望结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 01:47:32