我有一个OPL_Dates表,其开始日期和结束日期如下:
dbo.OPL_Dates
ID Start_date End_date
--------------------------------------
12345 1975-01-01 2001-12-31
12345 1989-01-01 2004-12-31
12345 2005-01-01 NULL
12345 2007-01-01 NULL
12377 2009-06-01 2009-12-31
12377 2013-02-07 NULL
12377 2010-01-01 2012-01-01
12489 2011-12-31 NULL
12489 2012-03-01 2012-04-01
我正在寻找的输出是:
ID Start_date End_date
-------------------------------------
12345 1975-01-01 2004-12-31
12345 2005-01-01 NULL
12377 2009-06-01 2009-12-31
12377 2010-01-01 2012-01-01
12377 2013-02-07 NULL
12489 2011-12-31 NULL
基本上,我想显示OPL期间(IF Any)之间的差距,否则我需要最小开始日期和最后结束日期,对于特定ID.NULL表示开放日期可以转换为“9999” -12-31" 。
答案 0 :(得分:1)
以下几乎可以满足您的需求:
with p as (
select v.*, sum(inc) over (partition by v.id order by v.dte) as running_inc
from t cross apply
(values (id, start_date, 1),
(id, coalesce(end_date, '2999-12-31'), -1)
) v(id, dte, inc)
)
select id, min(dte), max(dte)
from (select p.*, sum(case when running_inc = 0 then 1 else 0 end) over (partition by id order by dte desc) as grp
from p
) p
group by id, grp;
请注意,它会将“无限”结束日期从NULL
更改为2999-12-31。这是一种方便,因为NULL
在SQL Server升序排序中首先命令。
Here是一个SQL小提琴。
这是做什么的?它将日期拆分为单个列,其中1 / -1标志(inc
)表示记录是开始还是结束。然后,该标志的运行总和表示应该组合的组。当运行总和为0时,组已结束。要在正确的组中包含结束日期,需要反向运行总和 - 但这是一个细节。