消除并减少重叠日期范围

Jak*_*lås 10 sql t-sql sql-server stored-procedures sql-server-2005

我有一组日期范围,包括部分和完全重叠的日期,如下所示:

UserID  StartDate   EndDate 
======  ==========  ==========
1       2011-01-01  2011-01-02  <- A
1       2011-01-01  2011-01-10  <- A
1       2011-01-08  2011-02-15  <- A
1       2011-02-20  2011-03-10  <- B
2       2011-01-01  2011-01-20  <- C
2       2011-01-15  2011-01-25  <- C
Run Code Online (Sandbox Code Playgroud)

使用T-SQL,我想为每个用户创建一组新的数据,消除重叠数据,扩展范围并在需要时删除冗余数据,结果如下所示:

UserID  StartDate   EndDate 
======  ==========  ==========
1       2011-01-01  2011-02-15 ('A', three rows combined, extending the range)
1       2011-02-20  2011-03-10 ('B', no change, no overlaps here)
2       2011-01-01  2011-01-25 ('C', two rows combined)
Run Code Online (Sandbox Code Playgroud)

如果需要游标很好,但如果没有它就可以做得更好.

Ric*_*iwi 14

对于SQL Server 2005+

-- sample table with data
declare @t table(UserID int, StartDate datetime, EndDate datetime)
insert @t select
1, '20110101', '20110102' union all select
1, '20110101', '20110110' union all select
1, '20110108', '20110215' union all select
1, '20110220', '20110310' union all select
2, '20110101', '20110120' union all select
2, '20110115', '20110125'

-- your query starts below

select UserID, Min(NewStartDate) StartDate, MAX(enddate) EndDate
from
(
    select *,
        NewStartDate = t.startdate+v.number,
        NewStartDateGroup =
            dateadd(d,
                    1- DENSE_RANK() over (partition by UserID order by t.startdate+v.number),
                    t.startdate+v.number)
    from @t t
    inner join master..spt_values v
      on v.type='P' and v.number <= DATEDIFF(d, startdate, EndDate)
) X
group by UserID, NewStartDateGroup
order by UserID, StartDate
Run Code Online (Sandbox Code Playgroud)

笔记:

  1. 替换@t为您的表名

  • 值得一提的是,对于大于 `master..spt_values` 返回的行数的日期跨度,这将不起作用。在这种情况下,您可以将该表与自身交叉连接以提供更大的窗口大小。 (2认同)