2015-04-06 82 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