获取最多并包括 6 天缓冲区的连续唯一代码列表
Get list of unique codes that are consecutive with up to and including a 6 day buffer
问题
代码的开始和结束日期是什么运行ning?
我知道这与此处已有的其他 Gaps and Islands 问题类似,但我还没有发现因以下两个问题而变得复杂的问题:
- 一个代码可以多次开始和结束
- 一个代码可以 运行 最多有 6 天的间隔(这将在下面进一步解释)
数据
这是我的T-SQL数据:
Table
Code | Date
--------------------------------
1000 | 01-31-2015
1000 | 02-01-2015
1000 | 02-02-2015
1000 | 02-03-2015
1000 | 02-09-2015
1000 | 02-10-2015
1000 | 02-17-2015
1001 | 02-01-2015
1001 | 02-02-2015
1001 | 02-04-2015
1001 | 02-05-2015
1001 | 02-12-2015
1001 | 02-19-2015
理想解
我想要 sql 查询 return 的是:
Code | StartDate | EndDate | Run
--------------------------------------------------------
1000 | 01-31-2015 | 02-10-2015 | 1
1000 | 02-17-2015 | 02-17-2015 | 2
1001 | 02-01-2015 | 02-05-2015 | 3
1001 | 02-12-2015 | 02-12-2015 | 4
1001 | 02-19-2015 | 02-19-2015 | 5
为了进一步说明,让我们举个例子:
代码 1000 运行 从 01-31-2015 到 02-03-2015 连续几天。从 2015 年 2 月 9 日到 2015 年 2 月 10 日 运行ning 之前有 6 天的间隔。由于可以接受 6 天的间隔,因此 运行 的开始日期定义为 01-31-2015,结束日期定义为 02-03-2015。
然而,相比之下,代码 1001 运行s 在 02-12-2015 和 02-19-2015。由于它们之间有 7 天的间隔,因此它们不被视为在同一 运行.
非常感谢所有帮助,非常感谢您!
您需要确定群组的起点。在 SQL Server 2012+ 中,您可以使用 lag()
来达到这个目的。然后,通过累积给定行之前的开始次数,您就有了一个组。而且,有了一个组,你可以聚合。
这看起来像:
select code, min(date) as startdate, max(date) as enddate,
row_number() over (partition by code order by min(date)) as run
from (select t.*,
sum(IsGroupStart) over (partition by code order by date) as grp
from (select t.*,
(case when dateadd(day, -6, date) >
lag(date) over (partition by code order by date)
then 1 else 0
end) as IsGroupStart
from t
) t
) t
group by grp, code;
问题
代码的开始和结束日期是什么运行ning?
我知道这与此处已有的其他 Gaps and Islands 问题类似,但我还没有发现因以下两个问题而变得复杂的问题:
- 一个代码可以多次开始和结束
- 一个代码可以 运行 最多有 6 天的间隔(这将在下面进一步解释)
数据
这是我的T-SQL数据:
Table
Code | Date
--------------------------------
1000 | 01-31-2015
1000 | 02-01-2015
1000 | 02-02-2015
1000 | 02-03-2015
1000 | 02-09-2015
1000 | 02-10-2015
1000 | 02-17-2015
1001 | 02-01-2015
1001 | 02-02-2015
1001 | 02-04-2015
1001 | 02-05-2015
1001 | 02-12-2015
1001 | 02-19-2015
理想解
我想要 sql 查询 return 的是:
Code | StartDate | EndDate | Run
--------------------------------------------------------
1000 | 01-31-2015 | 02-10-2015 | 1
1000 | 02-17-2015 | 02-17-2015 | 2
1001 | 02-01-2015 | 02-05-2015 | 3
1001 | 02-12-2015 | 02-12-2015 | 4
1001 | 02-19-2015 | 02-19-2015 | 5
为了进一步说明,让我们举个例子:
代码 1000 运行 从 01-31-2015 到 02-03-2015 连续几天。从 2015 年 2 月 9 日到 2015 年 2 月 10 日 运行ning 之前有 6 天的间隔。由于可以接受 6 天的间隔,因此 运行 的开始日期定义为 01-31-2015,结束日期定义为 02-03-2015。
然而,相比之下,代码 1001 运行s 在 02-12-2015 和 02-19-2015。由于它们之间有 7 天的间隔,因此它们不被视为在同一 运行.
非常感谢所有帮助,非常感谢您!
您需要确定群组的起点。在 SQL Server 2012+ 中,您可以使用 lag()
来达到这个目的。然后,通过累积给定行之前的开始次数,您就有了一个组。而且,有了一个组,你可以聚合。
这看起来像:
select code, min(date) as startdate, max(date) as enddate,
row_number() over (partition by code order by min(date)) as run
from (select t.*,
sum(IsGroupStart) over (partition by code order by date) as grp
from (select t.*,
(case when dateadd(day, -6, date) >
lag(date) over (partition by code order by date)
then 1 else 0
end) as IsGroupStart
from t
) t
) t
group by grp, code;