TSQL:如何在

时间:2015-08-17 20:19:53

标签: sql-server date

我需要按FY分割这些日期,并获取日期之间的月数。我之前在How to duplicate Rows with new entries链接处回答了FY分组。 有以下日期: -

ID        Start dt    End dt         
2550     10/1/2010   9/30/2011               
2551     8/1/2014   7/31/2015           
2552     6/1/2013   5/31/2015              
2553    5/10/2012   6/11/2014  

我想要以下结果集:

ID   FY     # of Months     Start Dt    End Dt

2550    2011    12  10/1/2010   9/30/2011         

2551    2014    2   8/1/2014    9/30/2014          
2551    2015    10  10/1/2014   7/31/2015 

2552    2013    4   6/1/2013    9/30/2013                  
2552    2014    12  10/1/2013   9/30/2014             
2552    2015    8   10/1/2014   5/31/2015  

2553    2012    5   5/10/2012   9/30/2012                        
2553    2013    12  10/1/2012   9/30/2013                       
2553    2014    9   10/1/2013   6/11/2014  

FY将被视为明年10月至9月。

提前致谢!

1 个答案:

答案 0 :(得分:0)

构建这是一个有趣的查询:

declare @t table(id int, start_dt datetime, end_dt datetime)

Insert into @t(id, start_dt, end_dt) Values
        (2550, '2010/10/1', '2011/9/30')
        , (2551, '2014/8/1', '2015/7/31')           
        , (2552, '2013/6/1', '2015/5/31')
        , (2553, '2012/5/10', '2014/6/11')
        , (2554, '2012/5/10', '2012/11/1')
        , (2555, '2012/5/10', '2012/8/11')

; with data as(
    Select id, start_dt, end_dt, next_y = DATEADD(month, 9, DATEADD(year, DATEDIFF(year, 0, DATEADD(month, 3, start_dt)), 0))
    From @t
), split as (
    Select id, start_dt
        , end_dt = case when next_y > end_dt then end_dt else DATEADD(day, -1, next_y) end
        , next_y = DATEADD(year, 1, next_y)
    From data as d
    Union All
    Select s.id
        , DATEADD(day, 1, s.end_dt)
        , case when DATEADD(day, -1, next_y) < t.end_dt then DATEADD(day, -1, next_y) else t.end_dt end
        , next_y = DATEADD(year, 1, s.next_y)
    From split as s
    Inner Join @t as t on t.id = s.id
    Where s.end_dt < t.end_dt
)
Select ID, FY = year(end_dt), '# of Months' = DATEDIFF(month, start_dt, end_dt)+1, 'Start Dt' =  start_dt, 'End Dt' = end_dt 
From split
Order by id, start_dt, end_dt