0

这是我在 SQL-Sever 2005 模式下的数据

ID              FromDate    ToDate        Diff

ZIM145876-01    03/01/2011  02/29/2012    1
ZIM145876-01    03/01/2012  02/28/2013    1
ZIM145876-01    03/01/2013  02/28/2014    NULL


ZIM145881-02    02/01/2012  03/31/2012    1
ZIM145881-02    04/01/2012  06/30/2012    1
ZIM145881-02    07/01/2012  09/30/2012    1
ZIM145881-02    10/01/2012  03/31/2013    1
ZIM145881-02    04/01/2013  06/30/2013    NULL


ZIM145878-01    05/15/2010  05/14/2011    201
ZIM145878-01    12/01/2011  11/30/2012    1
ZIM145878-01    12/01/2012  11/30/2013    NULL

现在在第一个案例中,我想要

ZIM145876-01    03/01/2011  02/28/2014

ZIM145881-02    02/01/2012  06/30/2013

但是在第三种情况下,我们有两个相同 ID 的占用日期,这就是我想要的

ZIM145878-01    05/15/2010  05/14/2011
ZIM145878-01    12/01/2011  11/30/2013

所以任何提示都会受到高度赞赏(SQLFiddle

4

1 回答 1

1

这似乎可以完成这项工作。不幸的是,它在大型数据集上效率不会太高:

declare @t table (ID varchar(50),FromDate date,ToDate date, Diff int)
insert into @t(ID,FromDate,ToDate,Diff) values
('ZIM145876-01','20110301','20120229',1   ),
('ZIM145876-01','20120301','20130228',1   ),
('ZIM145876-01','20130301','20140228',NULL),
('ZIM145881-02','20120201','20120331',1   ),
('ZIM145881-02','20120401','20120630',1   ),
('ZIM145881-02','20120701','20120930',1   ),
('ZIM145881-02','20121001','20130331',1   ),
('ZIM145881-02','20130401','20130630',NULL),
('ZIM145878-01','20100515','20110514',201 ),
('ZIM145878-01','20111201','20121130',1   ),
('ZIM145878-01','20121201','20131130',NULL)

;With Islands as (
    select ID,FromDate,ToDate from @t t1 where not exists (select * from @t t2 where t2.ToDate = DATEADD(day,-1,t1.FromDate) and t1.ID = t2.ID)
    union all
    select i.ID,i.FromDate,t.ToDate
    from
        Islands i
            inner join
        @t t
            on
                i.ID = t.ID and
                i.ToDate = DATEADD(day,-1,t.FromDate)
)
select ID,FromDate,MAX(ToDate) from Islands
group by ID,FromDate

结果:

ID                                                 FromDate   
-------------------------------------------------- ---------- ----------
ZIM145878-01                                       2010-05-15 2011-05-14
ZIM145876-01                                       2011-03-01 2014-02-28
ZIM145878-01                                       2011-12-01 2013-11-30
ZIM145881-02                                       2012-02-01 2013-06-30

如果将占用记录为半开放时间间隔(例如,Inclusive FromDate、Exclusive ToDate),可能会更有效——因为这样我们就不必调用DATEADD来查找时间段连接在一起的位置。

我不知道这个Diff专栏是关于什么的,我也没有使用它。

于 2013-08-15T07:32:58.283 回答