首页 > 解决方案 > 对连续的行序列进行分组

问题描述

我正在尝试对 SQL Server 上布尔值为 true 的连续行进行分组。例如,以下是一些源数据的样子:

AccountID | ID | IsTrue | Date
-------------------------------
1         | 1  | 1      | 1/1/2013
1         | 2  | 1      | 1/2/2013
1         | 3  | 1      | 1/3/2013
1         | 4  | 0      | 1/4/2013
1         | 5  | 1      | 1/5/2013
1         | 6  | 0      | 1/6/2013
1         | 7  | 1      | 1/7/2013
1         | 8  | 1      | 1/8/2013
1         | 9  | 1      | 1/9/2013

这就是我想要的输出

AccountID | Start    | End
-------------------------------
1         | 1/1/2013 | 1/3/2013
1         | 1/7/2013 | 1/9/2013

我有一种预感,有一些按分区分组的技巧可以使这项工作有效,但我一直无法弄清楚。我在使用 LAG 方面取得了一些进展,但无法将它们放在一起。

谢谢您的帮助!

标签: sqlsql-server

解决方案


这是间隙和孤岛问题的一个例子。对于此版本,您只需要为每个isTrue. 对于相同的相邻值,从每个日期中减去此天数是一个常数:

select accountId, isTrue, min(date), max(date)
from (select t.*,
             row_number() over (partition by accountId, isTrue order by date) as seqnum
      from t
     ) t
group by accountId, isTrue, dateadd(day, -seqnum, date);

这定义了所有组。如果我假设您只想要超过 1 天的“1”值,那么:

select accountId, isTrue, min(date), max(date)
from (select t.*,
             row_number() over (partition by accountId, isTrue order by date) as seqnum
      from t
      where isTrue = 1
     ) t
group by accountId, isTrue, dateadd(day, -seqnum, date)
having count(*) > 1;

推荐阅读