2016-02-28 109 views
1

我需要在年份和季度中显示分配成员资格。我使用SQL Server 2012的如何在T-SQL中将一行中的时间范围拆分为不同行中的不同季度

的数据是这样的:

CREATE TABLE MyTable 
(
    MyGroup nvarchar(10) NULL, 
    StartTime nvarchar(10) NULL, 
    EndTime nvarchar (10) NULL, 
    Quantity int NULL 
) 

Insert into MyTable 
Values ('a', '7/1/2014', '6/30/20116', '10'), 
     ('b', '12/1/2013', '11/30/2014', '8') 

期望的结果:

MyGroup StartTime EndTime Year Quarter Quantity 
a 7/1/2014 6/30/2016 2014 2014-Q3 10 
a 7/1/2014 6/30/2016 2014 2014-Q4 10 
a 7/1/2014 6/30/2016 2015 2015-Q1 10 
a 7/1/2014 6/30/2016 2015 2015-Q2 10 
a 7/1/2014 6/30/2016 2015 2015-Q3 10 
a 7/1/2014 6/30/2016 2015 2015-Q4 10 
a 7/1/2014 6/30/2016 2016 2016-Q1 10 
a 7/1/2014 6/30/2016 2016 2016-Q2 10 
b 12/1/2013 11/30/2014 2013 2013-Q4 8 
b 12/1/2013 11/30/2014 2014 2014-Q1 8 
b 12/1/2013 11/30/2014 2014 2014-Q2 8 
b 12/1/2013 11/30/2014 2014 2014-Q3 8 
+1

你应该类型的列['DATE'](https://msdn.microsoft.com/en-us/library/bb630352.aspx),而不是使用'VARCHAR'被存储日期。如果你不这样做(你应该真的),至少将你的日期存储为'YYYYMMDD'。 –

回答

1

enter image description here
可以尝试下面的查询。您需要通过在表中引入索引来优化查询,以防您使用大数据执行此操作。

;With Quarters as (
    select MyGroup,StartTime as StartTime1 ,DATEADD(quarter,DATEDIFF(quarter,0,StartTime),0) as StartTime , Endtime, Quantity from MyTable 
    union all 
    select MyGroup,StartTime1,DATEADD(quarter,1,StartTime) , Endtime , Quantity 
    from Quarters 
    where StartTime < DATEADD(quarter,DATEDIFF(quarter,0,EndTime),0) 
) 
select MyGroup, Convert(varchar(10),StartTime,110) as StartTime, Convert(varchar(10),EndTime,110) as EndTime, DATEPART(YEAR,StartTime) as Years, 
    -- CONVERT(varchar(3),StartTime,109) + ' ' + CONVERT(varchar(4),StartTime,120) as QuarterMonth , 
    CONVERT(varchar(4),StartTime,120) + '-Q' + 
    CAST(CEILING(CAST(month(StartTime) AS decimal(4,2))/3) AS char(1)) AS SelectQuarter , Quantity 
from Quarters order by Quantity desc 
1

有两种方式,使这个:

  1. 通过创建3个查找表(QuartersYearsYearQuarters)来帮助我n中的加入,这将会使查询很容易

  2. 不改变数据库或创建任何额外的表,但是这将会使查询非常复杂,它会包含一些重复的代码

1

这里我使用一个Numbers table将您的开始 - >结束范围内的行分成几天,然后逐季分组,然后提取年份:季度。

declare @MyTable table 
(
    MyGroup nvarchar(10) NULL, 
    StartTime date NULL, 
    EndTime date NULL, 
    Quantity int NULL 
); 

Insert into @MyTable Values 
('a', '7/1/2014', '6/30/2016', '10'), 
('b', '12/1/2013', '11/30/2014', '8') 


;with 
DaysBetween (MyGroup, MyDate) as 
( select mt.MyGroup, 
      dateadd(day, n-1, mt.StartTime) 
    from @MyTable mt 
    cross 
    apply dbo.Number n 
    where n.N <= datediff(day, mt.StartTime, mt.EndTime) 
), 
AsQuarters (MyGroup, StartOfQuarter) as 
( select MyGroup, dateadd(quarter, datediff(quarter, 0, MyDate), 0) 
    from DaysBetween 
    group 
    by  MyGroup, dateadd(quarter, datediff(quarter, 0, MyDate), 0) 
) 
select MyGroup, datepart(year, StartOfQuarter), datepart(quarter, StartOfQuarter) 
from AsQuarters 
order 
by  1, 2, 3; 

返回:

MyGroup year quarter 
------- ---- ------- 
a  2014 3 
a  2014 4 
a  2015 1 
a  2015 2 
a  2015 3 
a  2015 4 
a  2016 1 
a  2016 2 
b  2013 4 
b  2014 1 
b  2014 2 
b  2014 3 
b  2014 4 <-- Did you forget this one? 
相关问题