2014-06-16 232 views
0

我有這樣TSQL:結合日期範圍

date  | rate 
2014-01-01 | 100 
2014-01-02 | 100 
2014-01-03 | 1 
2014-01-04 | 1 
2014-01-05 | 100 
2014-01-06 | 100 
2014-01-07 | 1 
2014-01-08 | 1 
2014-01-09 | 100 
2014-01-10 | 100 
2014-01-11 | 100 
2014-01-12 | 100 

表我想獲得以下

date start  | date end | rate 
2014-01-01  | 2014-01-02 | 100 
2014-01-03  | 2014-01-04 | 1 
2014-01-05  | 2014-01-06 | 100 
2014-01-07  | 2014-01-08 | 1 
2014-01-09  | 2014-01-12 | 100 

等。當然,數字可能會有所不同。

我該如何在TSQL中做到這一點?爲了以防萬一,我使用了SQL Server 2012。

+0

是日期列連續? –

+0

是的,它包含幾年的利率。這是一天一次的費用。 –

+0

最後一個例子不是連續的,即所有先前的增量都是2天,最後一個增加4個。是你預先定義的範圍(可能是不同的),還是你總是期望它們遵循一個模式? – sarin

回答

2

這個問題命名爲「間隙和孤島問題」。我不能在這裏發表的答案,所以我創建了小提琴:

SQL FIDDLE

0

試試這個:

;with cte as 
(select [date] d,rate, case when lead(rate, 1, 0) over (order by [date]) = rate then 1 else 0 end ld 
from tbl), 

filtered as 
(select *, rank() over (partition by ld order by d) rn 
from cte) 

select f.d [date start], s.d [date end], f.rate 
from filtered f 
inner join filtered s on f.rn = s.rn 
and f.ld = 1 and s.ld = 0 

哈姆雷特的答案是當然的,正確的。我想提出一個替代解決方案。我們使用LEAD分析函數來確定新值範圍的開始,然後使用RANK來獲取與每個範圍所需的開始和結束日期對應的行。

演示here

UPDATELEAD可從SQL Server 2012開始使用,所以雖然它可以在OP的情況下工作,但它不適用於舊版本。

+2

重新檢查結果。 –

+0

@HamletHakobyan感謝您指出我以前的查詢中的錯誤。我現在更新了它。 –

+1

值得一提的是'LEAD'只支持SQL Server 2012以上版本。 – adaskos