2016-10-25 10 views
0

Sql Server 2012(T-SQL)では、不在の日付の一覧を分析し、データをまとめて月ごとにまとめたデータを並べ替えたいと思います。グループ対応する月と合計時間の日付

例:ここでは

は、生データのリストの下

TimeSheetID UserID LeaveID StartDate  EndDate  Duration 
     1  779  1  01/01/2016 01/01/2016  7.5 
     2  779  1  02/01/2016 02/01/2016  7.5 
     3  779  2  03/01/2016 03/01/2016  7.5 
     4  1021  3  01/01/2016 02/01/2016  7.5 
     5  999  4  30/01/2016 30/01/2016  7.5 
     6  999  4  31/01/2016 31/01/2016  7.5 
     7  999  4  01/02/2016 01/02/2016  7.5 
     8  999  4  02/02/2016 02/02/2016  7.5 
     9  123  5  27/02/2016 28/02/2016  12 
     10  123  5  29/02/2016 01/03/2016  12 
     11  123  5  01/03/2016 02/03/2016  12 

が優先出力されている、あなたはほとんどの場合、データが要約されている、しかし、日付が新しい月に陥るところていることがわかりますデータは新月グループに分離されます。

同様に、日付範囲が2日間にわたって経過すると、これは夜間シフトとして分類されるため、開始日はグループ化係数として、対応する月別のグループ化になります。

UserID LeaveID StartDate  EndDate  Duration 
    779  1  01/01/2016 02/01/2016  15 
    779  2  03/01/2016 03/01/2016  7.5 
    1021  3  01/01/2016 02/01/2016  7.5 
    999  4  30/01/2016 31/01/2016  15 
    999  4  01/01/2016 02/02/2016  15 
    123  5  27/02/2016 01/03/2016  24 
    123  5  01/03/2016 02/03/2016  12 
+1

私はそれを得ることはありませんが時間を普及していない場合。 'LeaveId' 1は' LeaveId' 5ではなく、一つの行にどのように崩壊しましたか? –

+0

ソーステーブル行 '123 5 01/02/2016 02/03/2016 12'は正しいか、または入力ミスですか? – Searching

+0

'Leave Id' 5は、新しい月にその不在の1つの期間として始まる1行に倒れることはできません – SoupOfStars

答えて

0

最後の2つの値が切断されています。今

Select UserID 
     ,LeaveID 
     ,StartDate = Min(KeyDate) 
     ,EndDate = Max(KeyDate) 
     ,Duration = cast(Sum(PerDay) as decimal(10,2)) 
From (Select KeyDate=RetVal From [dbo].[udf-Range-Date]((Select min(StartDate) from @YourTable),(Select max(EndDate) from @YourTable),'DD',1)) A 
Join (Select *,PerDay = Duration/(1+DateDiff(DD,StartDate,EndDate)) From @YourTable) B on (A.KeyDate Between B.StartDate and B.EndDate) 
Group By 
     UserID 
     ,LeaveID 
     ,Month(KeyDate) 
Order By LeaveID 

戻り

enter image description here

を(以下の強調表示)、私は、ダイナミックな日付範囲を作成するために、TVFを使用していますが、タリー/カレンダー表にもトリックを行います。

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<[email protected] 
) 
/* 
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) 
*/ 
0

は今、あなたは数ヶ月間で

Select UserID 
     ,LeaveID 
     ,StartDate = Min(StartDate) 
     ,EndDate = Max(EndDate) 
     ,Duration = sum(Duration) 
From @YourTable 
Group By 
     UserID 
     ,LeaveID 
     ,Month(StartDate) 
Order By LeaveID 

戻り

enter image description here

関連する問題