我仍然是我英语的新手和借口。你看我有两个人有不同的时间段,如果它们是连续的,我想汇总这些时期。我不知道如何使用例如与下一行相关的min()
和max()
函数或比较日期之前的行。或者有更简单的方法来解决这个问题?我只有没有滞后和引导功能的SQL Server 2008 R2。
示例数据:
DECLARE @Table TABLE(
PersonID INT,
FROM date,
TO date
)
INSERT INTO @Table SELECT 1,'2011-01-01','2011-04-30'
INSERT INTO @Table SELECT 1,'2011-05-01','2011-08-31'
INSERT INTO @Table SELECT 1,'2011-09-01','2011-12-31'
INSERT INTO @Table SELECT 1,'2012-01-01','2012-03-31'
INSERT INTO @Table SELECT 2,'2011-03-01','2011-06-30'
INSERT INTO @Table SELECT 2,'2011-07-01','2011-10-31'
INSERT INTO @Table SELECT 2,'2013-01-01','2013-04-30'
INSERT INTO @Table SELECT 2,'2013-05-01','2013-08-31'
我期待这样的事情并特别注意PersonID 2:
PersonID FROM TO
1 , 2011-01-01 , 2012-03-31
2 , 2011-03-01 , 2011-10-31
2 , 2013-01-01 , 2013-08-31
答案 0 :(得分:1)
这是一个难以解决的问题,使用累积总和lag()
或lead()
会更容易。你仍然可以做这项工作。我更喜欢使用相关子查询来表达它。
逻辑首先确定哪些记录通过重叠连接到“下一个”记录。以下查询使用此逻辑来定义OverlapWithPrev
。
select *
from (select t.*,
(select top 1 1
from t t2
where t2.personid = t.personid and
t2.fromd < t.fromd and
t2.tod >= dateadd(d, -1, t.fromd)
order by t2.fromd
) as OverlapWithPrev
from t
) t
如果有前一条记录,则会显示1
的值;如果没有,则会显示NULL
。
然后使用此信息,查询然后为每个记录查找 next 记录,该记录与前一个记录不重叠(并且在同一个人身上)。如果有一系列重叠记录,则所有记录都具有相同的下一条记录,下一条记录用于聚合。
以下是完整查询:
with tp as
(select *
from (select t.*,
(select top 1 1
from t t2
where t2.personid = t.personid and
t2.fromd < t.fromd and
t2.tod >= dateadd(d, -1, t.fromd)
order by t2.fromd
) as OverlapWithPrev
from t
) t
)
select personid, min(fromd) as fromd, max(tod) as tod
from (select tp.*,
(select top 1 fromd
from tp tp2
where tp2.OverlapWithPrev is null and
tp2.personid = tp.personid and
tp2.fromd > tp.fromd
) as NextFromD
from tp
) tp
group by personid, NextFromD;
Here是一个SQLFiddle来展示它是如何工作的。