2012-12-05 212 views
1

考慮到以下一組數據,我試圖確定如何選擇組合日期範圍的開始和結束日期,當它們相互交叉時。查找多組日期之間的最小和最大日期

例如,對於PartNum 115678,我希望我的最終結果集顯示日期範圍2012/01/01 - 2012/01/19(自日期範圍相交以來合併的行1,2和4)和2012/02/01 - 2012/03/28(第3行,因爲這些不與之前發現的範圍)。

對於PartNum 213275,我想選擇該零件的唯一行,2012/12/01 - 2013/01/01

example-data

編輯: 我目前正在與下面的SQL語句玩耍,但它不給我正是我需要的。

with DistinctRanges as (
    select distinct 
     ha1.PartNum "PartNum", 
     ha1.StartDt "StartDt", 
     ha2.EndDt "EndDt" 
    from dbo.HoldsAll ha1 
    inner join dbo.HoldsAll ha2 
     on ha1.PartNum = ha2.PartNum 
    where 
     ha1.StartDt <= ha2.EndDt 
     and ha2.StartDt <= ha1.EndDt 
) 
select 
    PartNum, 
    StartDt, 
    EndDt 
from DistinctRanges 

以下是編輯顯示的查詢結果:

results from inline query

回答

2

你最好有一個持久的日曆表,但如果你不這樣做,下面的意志CTE特別創建它。 TOP(36000)部分足以讓您在同一行上獲得10年的日期('20100101')。

SQL Fiddle

MS SQL Server 2008的架構設置

create table data (
    partnum int, 
    startdt datetime, 
    enddt datetime, 
    age int 
); 
insert data select 
12345, '20120101', '20120116', 15 union all select 
12345, '20120115', '20120116', 1 union all select 
12345, '20120201', '20120328', 56 union all select 
12345, '20120113', '20120119', 6 union all select 
88872, '20120201', '20130113', 43; 

查詢1

with Calendar(thedate) as (
    select TOP(36600) dateadd(d,row_number() over (order by 1/0),'20100101') 
     from sys.columns a 
cross join sys.columns b 
cross join sys.columns c 
), tmp as (
    select partnum, thedate, 
      grouper = datediff(d, dense_rank() over (partition by partnum order by thedate), thedate) 
    from Calendar c 
    join data d on d.startdt <= c.thedate and c.thedate <= d.enddt 
) 
select partnum, min(thedate) startdt, max(thedate) enddt 
    from tmp 
group by partnum, grouper 
order by partnum, startdt 

Results

| PARTNUM |       STARTDT |       ENDDT | 
------------------------------------------------------------------------------ 
| 12345 | January, 01 2012 00:00:00+0000 | January, 19 2012 00:00:00+0000 | 
| 12345 | February, 01 2012 00:00:00+0000 | March, 28 2012 00:00:00+0000 | 
| 88872 | February, 01 2012 00:00:00+0000 | January, 13 2013 00:00:00+0000 | 
+0

謝謝你的詳細解答。我會試一試。 – acedanger

+1

@RichardTheKiwi:我剛剛遇到你用T-SQL編寫的掃雷碼,現在只是我的心靈爆發,而下一刻我看到你的回答這個問題太簡單了。 – praveen

+0

@Praveen感謝您的讚揚:) – RichardTheKiwi