【问题标题】:Sql to repeat rows for all the months based on Startdate and EndDateSql 根据 Startdate 和 EndDate 重复所有月份的行
【发布时间】:2017-03-02 18:13:34
【问题描述】:

我有一个“配额”表,其中包含每个团队的配额数量以及配额的开始日期和结束日期。这是样本配额表

'StartDate' 是配额的开始日期,'StartMonthYear' 是月份+开始日期的年份,'EndDate' 是配额的结束日期,'QuotaAmount' 是 startdate 和 EndDate 之间的配额,TeamName 是分配此配额的团队名称到。

现在我如何才能按月生成特定配额的重复行? 我正在寻找的示例输出是

这里的 T1 团队有 3 个月的配额,所以我希望每个月有 3 条不同的记录,开始日期为月份开始日期,“结束日期”为月底日期。

注意:配额总是从每月的 1 天开始,到每月的最后一天结束。

提前致谢

【问题讨论】:

  • 我的建议是通过将“逻辑”放在存储过程中来为自己简化这一点。我的感觉是,在单个 SQL 查询中执行此操作会不必要地麻烦。

标签: sql sql-server sql-server-2008


【解决方案1】:

如果您没有日历表,则可以使用生成动态日期/时间范围的 TVF

Declare @Date1 date = '2016-01-01'  -- These could be a query for min/max dates
Declare @Date2 date = '2016-12-31' 

Select A.StartDate
      ,StartMonthYear = month(A.StartDate)*10000+Year(A.StartDate)
      ,A.EndDate
      ,B.QuotaAmount
      ,B.TeamName
 From (Select StartDate=RetVal,EndDate=DateAdd(DD,-1,DateAdd(MM,1,RetVal)) From [dbo].[udf-Range-Date](@Date1,@Date2,'MM',1)) A
 Join YourTable B
   on A.StartDate between B.StartDate and B.EndDate
 Order by TeamName,A.StartDate

返回

UDF(如果需要)

CREATE FUNCTION [dbo].[udf-Range-Date] (@R1 datetime,@R2 datetime,@Part varchar(10),@Incr int)
Returns Table
Return (
    with cte0(M)   As (Select 1+Case @Part When 'YY' then DateDiff(YY,@R1,@R2)/@Incr When 'QQ' then DateDiff(QQ,@R1,@R2)/@Incr When 'MM' then DateDiff(MM,@R1,@R2)/@Incr When 'WK' then DateDiff(WK,@R1,@R2)/@Incr When 'DD' then DateDiff(DD,@R1,@R2)/@Incr When 'HH' then DateDiff(HH,@R1,@R2)/@Incr When 'MI' then DateDiff(MI,@R1,@R2)/@Incr When 'SS' then DateDiff(SS,@R1,@R2)/@Incr End),
         cte1(N)   As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)),
         cte2(N)   As (Select Top (Select M from cte0) Row_Number() over (Order By (Select NULL)) From cte1 a, cte1 b, cte1 c, cte1 d, cte1 e, cte1 f, cte1 g, cte1 h ),
         cte3(N,D) As (Select 0,@R1 Union All Select N,Case @Part When 'YY' then DateAdd(YY, N*@Incr, @R1) When 'QQ' then DateAdd(QQ, N*@Incr, @R1) When 'MM' then DateAdd(MM, N*@Incr, @R1) When 'WK' then DateAdd(WK, N*@Incr, @R1) When 'DD' then DateAdd(DD, N*@Incr, @R1) When 'HH' then DateAdd(HH, N*@Incr, @R1) When 'MI' then DateAdd(MI, N*@Incr, @R1) When 'SS' then DateAdd(SS, N*@Incr, @R1) End From cte2 )

    Select RetSeq = N+1
          ,RetVal = D 
     From  cte3,cte0 
     Where D<=@R2
)
/*
Max 100 million observations -- Date Parts YY QQ MM WK DD HH MI SS
Syntax:
Select * from [dbo].[udf-Range-Date]('2016-10-01','2020-10-01','YY',1) 
Select * from [dbo].[udf-Range-Date]('2016-01-01','2017-01-01','MM',1) 
*/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-22
    相关资源
    最近更新 更多