SQL Server提取重叠日期范围(返回跨越其他日期的日期)

时间:2014-07-21 19:31:04

标签: sql sql-server database tsql

我如何从下表中提取重叠日期?

ID  Name        StartDate   EndDate     Type
==============================================================
1   John Smith  01/01/2014  31/01/2014  A
2   John Smith  20/01/2014  20/02/2014  B
3   John Smith  01/03/2014  28/03/2014  A
4   John Smith  18/03/2014  24/03/2014  B
5   John Smith  01/07/2014  31/07/2014  A
6   John Smith  15/07/2014  31/07/2014  B
7   John Smith  25/07/2014  25/08/2014  C

根据约翰史密斯的第一个例子,2014年1月1日至2014年1月31日的日期与2014年1月20日至2014年2月20日重叠,所以我期待重叠的期间回到20 / 01/2014至31/01/2014。

最终结果将是:

ID  Name        StartDate   EndDate
==================================================
8   John Smith  20/01/2014  31/01/2014
9   John Smith  18/03/2014  24/03/2014
10  John Smith  15/07/2014  31/07/2014
11  John Smith  25/07/2014  31/07/2014

2014年8月10日需要提供帮助

除上述请求外,我正在寻求有关如何获得以下结果的帮助或指导,其中应包括重叠的日期和不重叠的日期。 ID列无关紧要。

ID  Name        StartDate   EndDate     Type
==================================================
1   John Smith  01/01/2014  19/01/2014  A
8   John Smith  20/01/2014  31/01/2014  AB
2   John Smith  01/02/2014  20/02/2014  B
3   John Smith  01/03/2014  17/03/2014  A
9   John Smith  18/03/2014  24/03/2014  AB
3   John Smith  25/03/2014  28/03/2014  A
5   John Smith  01/07/2014  14/07/2014  A
10  John Smith  15/07/2014  31/07/2014  AB
11  John Smith  25/07/2014  31/07/2014  ABC
7   John Smith  01/08/2014  25/08/2014  C

虽然以下图片并不完全反映上述内容,但为了便于说明,我有兴趣在同一结果集中查看重叠的日期(红色)和不重叠的日期(天蓝色)。 / p>

http://imgur.com/SeR9sY1

1 个答案:

答案 0 :(得分:1)

如果您只想重叠句点,可以通过自我加入来获得。请注意,如果在某些日期重叠两个以上的期间,结果可能会多余。

select ft.name,
       (case when max(ft.startdate) > max(ft2.startdate) then max(ft.startdate)
             else max(ft2.startdate)
        end) as startdate,
       (case when min(ft.enddate) > min(ft2.enddate) then min(ft.enddate)
             else min(ft2.enddate)
        end) as enddate
from followingtable ft join
     followingtable ft2
     on ft.name = ft2.name and
        ft.id < ft2.id and
        ft.startdate <= ft2.enddate and
        ft.enddate > ft2.startdate
group by ft.name, ft.id, ft2.id;

这不会分配id。您可以使用row_number()和偏移量来完成此操作。