2015-04-06 32 views
1

比方說,我在一個表中有下列值分離行

Package | Start Date | End date 
--------------------------------- 
PKG123 | 01-02-2013 | 31-01-2016 
PKG456 | 15-06-2010 | 14-06-2014 

我想寫一個select語句,應該給我的結果,如:

Package | Start Date | End date 
----------------------------------- 
PKG123 | 01-02-2013 | 31-01-2014 
PKG123 | 01-02-2014 | 31-01-2015 
PKG123 | 01-02-2015 | 31-01-2016 
PKG456 | 15-06-2010 | 14-06-2011 
PKG456 | 15-06-2011 | 14-06-2012 
PKG456 | 15-06-2012 | 14-06-2013 
PKG456 | 15-06-2013 | 14-06-2014 

是有一種方法可以在TSQL中執行它?

請注意,我不是在查找兩個日期之間的日期的完整列表,而是查找基於12個月的時間將一行分成多行的完整列表。

我正在使用SQL Server 2008 R2。

+0

是否有很多行?我假設你可以用遞歸CTE做到這一點,但是如果產生的行數和年數很大,可能會導致性能問題。 –

+0

@JamesZ這張桌子有大約9500行,從2010年至今可能涉及的年數會隨着時間的推移而增加。 – xaahir

回答

1

這是如何使用遞歸CTE做到這一點:

;with CTE as (
    select package, startDate, EndDate from data 
    union all 
    select package, dateadd(month, 12, startDate), EndDate 
    from CTE where EndDate > dateadd(month, 12, startDate) 
) 

select 
    package, 
    startdate, 
    case when enddate <= dateadd(month, 12, startdate) 
    then enddate else dateadd(day, -1, dateadd(month, 12, startdate)) end 
    as enddate 
From 
    CTE 
order by package, startdate 

的CTE會從表中的行,然後遞歸地選擇新行,如果開始日期+ 12月份是小於結束日期。 CTE以外的選擇將確定要使用的行中的哪個值,startdate + 12個月或結束日期。

SQL小提琴:http://sqlfiddle.com/#!6/5bfbf/4