2016-10-19 3 views
0

以下に示すような連続的な状態データを持つテーブルからデータを引き出すSQLクエリが必要です。ある時間窓のデータを1時間/ 1日というように取得したい場合は、レコードをフィルタリングして状態情報をピボットする必要があります。 ':50:2016年8月11日23 00.000' FROM:TO前後の行

フィルタ '2016年8月13日01:15:00.000' - 85分

フィルタbelow-黄色で強調表示されるよう以下の通りです -

私は、次のフィルタを与えた場合、その後、

DECLARE @StartDate DATETIME = '2016-08-11 23:50:00.000' 
DECLARE @EndDate DATETIME = '2016-08-15 01:15:00.000' 

理想的には、それのように、時間窓を検討すべきである -

2016-08-11 23:50:00 to 2016-08-12 01:15:00 - 85 minutes 
2016-08-12 23:50:00 to 2016-08-13 01:15:00 - 85 minutes 
2016-08-13 23:50:00 to 2016-08-14 01:15:00 - 85 minutes 
2016-08-14 23:50:00 to 2016-08-15 01:15:00 - 85 minutes 
2016-08-15 23:50:00 to 2016-08-16 01:15:00 - 85 minutes 

など....

UPDATE 3

enter image description here

は、誰かがこのクエリで私を助けることができますか?

サンプルデータ -

create table #temp1 ([State] varchar(20),StartTimeStamp Datetime2, EndTimeStamp Datetime2, DurationInSeconds int) 
Insert into #temp1 values('Away',  '2016-08-11 23:40:00.000000',   '2016-08-11 23:45:00.000000', 300 ) 
,('Appear Away','2016-08-11 23:45:00.000000',   '2016-08-11 23:50:00.000000', 300) 
,('Available', '2016-08-11 23:50:00.000000',   '2016-08-11 23:55:00.000000', 300) 
,('Available','2016-08-11 23:55:00.000000',    '2016-08-11 23:59:59.000000', 299) 
,('Away',  '2016-08-12 00:00:00.000000',   '2016-08-12 00:05:00.000000', 300) 
,('Offline', '2016-08-12 00:05:00.000000',   '2016-08-12 00:15:00.000000', 600) 
,('Away',  '2016-08-12 00:15:00.000000',   '2016-08-12 00:30:00.000000', 900) 
,('Appear Away','2016-08-12 00:30:00.000000',   '2016-08-12 01:15:00.000000', 2700) 
,('Away',  '2016-08-12 01:15:00.000000',   '2016-08-12 01:30:00.000000', 900) 
,('Offline', '2016-08-12 01:30:00.000000',   '2016-08-12 18:30:00.000000', 64800) 
,('Appear Away','2016-08-12 18:30:00.000000',   '2016-08-12 23:30:00.000000', 18000) 
,('Available', '2016-08-12 23:30:00.000000',   '2016-08-12 23:45:00.000000', 900) 
,('Away',  '2016-08-12 23:45:00.000000',   '2016-08-12 23:50:00.000000', 300) 
,('Offline', '2016-08-12 23:50:00.000000',   '2016-08-12 23:55:00.000000', 300) 
,('Available', '2016-08-12 23:55:00.000000',   '2016-08-12 23:59:59.000000', 299) 
,('Away',  '2016-08-13 00:00:00.000000',   '2016-08-13 00:05:00.000000', 300) 
,('Offline', '2016-08-13 00:05:00.000000',   '2016-08-13 00:15:00.000000', 600) 
,('Away',  '2016-08-13 00:15:00.000000',   '2016-08-13 00:30:00.000000', 900) 
,('Appear Away','2016-08-13 00:30:00.000000',   '2016-08-13 01:15:00.000000', 2700) 
,('Away',  '2016-08-13 01:15:00.000000',   '2016-08-13 01:30:00.000000', 900) 

アップデート2:予想される出力:

enter image description here

+1

質問を編集して、取得したい結果を表示してください。また、赤い線を説明するかもしれません。それはどういう意味ですか? –

+0

期待した結果を表示してください。 – NEER

+0

@GordonLinoffの質問への変更 –

答えて

2

することはでき以下のように:

DECLARE @StartDate DATETIME = '2016-08-8 17:00:00.000' 
DECLARE @EndDate DATETIME = '2016-08-15 18:00:00.000' 

;WITH TmpCte 
AS 
(
    SELECT 
     T.*, 
     IIF(T.StartTimeStamp < DATEADD(ms, DATEDIFF(ms, '00:00:00', CAST(@StartDate AS TIME)), CAST(CAST(T.StartTimeStamp AS DATE) AS DATETIME)), 
       DATEADD(ms, DATEDIFF(ms, '00:00:00', CAST(@StartDate AS TIME)), CAST(CAST(T.StartTimeStamp AS DATE) AS DATETIME)), 
       T.StartTimeStamp) AS TmpStart, 
     IIF(T.EndTimeStamp > DATEADD(ms, DATEDIFF(ms, '00:00:00', CAST(@EndDate AS TIME)), CAST(CAST(T.EndTimeStamp AS DATE) AS DATETIME)), 
       DATEADD(ms, DATEDIFF(ms, '00:00:00', CAST(@EndDate AS TIME)), CAST(CAST(T.EndTimeStamp AS DATE) AS DATETIME)), 
       T.EndTimeStamp) AS TmpEnd   
    FROM 
     #temp T 
), CTE as (
    SELECT * FROM 
    (
      SELECT 
      *, 
      ABS(DATEDIFF(SECOND, TmpStart, TmpEnd)) TmpDuration 
      FROM TmpCte 
      where 
      TmpStart >= @StartDate and 
      TmpEnd <= @EndDate AND 
      TmpEnd > TmpStart  
    ) A 
    PIVOT(SUM(TmpDuration) 
    FOR state IN ([Appear Away],[Available],[Away],[Offline],[online]) ) as  Pivottable 

) 
    select CAST(StartTimestamp as Date) as LocalDate,SUM([Available]) as [Available] , SUM([Away]) as Away,SUM([Online]) as [Online], 
    SUM(Offline) as [Offline] 
    from CTE 
    group by CAST(StartTimestamp as Date) 

結果:

+------------+-----------+------+--------+---------+ 
| LocalDate | Available | Away | Online | Offline | 
+------------+-----------+------+--------+---------+ 
| 2016-08-11 |  600 | 1039 | 163 |  600 | 
+------------+-----------+------+--------+---------+ 
+1

ありがとう@NEER。完璧な答え。 :) –

0

次のようにしてください。

DECLARE @StartDate DATETIME = '2016-08-11 23:45:00.000' 
DECLARE @EndDate DATETIME = '2016-08-12 01:00:00.000' 

;WITH TmpCte 
AS 
(
    SELECT 
     T.*, 
     IIF(T.StartTimeStamp < @StartDate, 
       @StartDate, 
       T.StartTimeStamp) AS TmpStart, 
     IIF(T.EndTimeStamp > @EndDate,    
       @EndDate, 
       T.EndTimeStamp) AS TmpEnd   
    FROM 
     #temp T 
), CTE as (
    SELECT * FROM 
    (
      SELECT 
      *, 
      ABS(DATEDIFF(SECOND, TmpStart, TmpEnd)) TmpDuration 
      FROM TmpCte 
      where 
      TmpStart >= @StartDate and 
      TmpEnd <= @EndDate AND 
      TmpEnd > TmpStart  
    ) A 
    PIVOT(SUM(TmpDuration) 
    FOR state IN ([Appear Away],[Available],[Away],[Offline],[online]) ) as  Pivottable 

) 
    SELECT 
    CAST(StartTimestamp as Date) as LocalDate, 
    SUM([Appear Away]) as [Appear Away], 
    SUM([Available]) as [Available] , 
    SUM([Away]) as Away,SUM([Online]) as [Online], 
    SUM(Offline) as [Offline] 
    from CTE 
    group by CAST(StartTimestamp as Date) 
+0

私は複数の日のスパンがある場合、これは動作しません。私が午後11時30分から午前1時まで、そして複数の日にシフトした場合、それは動作しません。しかし、あなたの最初の答えでは、シフトは毎日午後5時(17:00)から午後6時(18:00)までで、正しく動作していました。 –

+0

以下のフィルタを指定すると、 DECLARE @ -StartDate DATETIME = '2016-08-11 23:00:00.000' DECLARE @ -EndDate DATETIME = '2016-08-15 01:00:00。000 ' 理想的には、タイムウィンドウを- 2016-08-11 23:00:00から2016-08-12 01:00:00としてください。 2016-08-12 23:00:00 to 2016-08-13 01:00:00 2016-08-13 23:00:00〜2016-08-14 01:00:00 2016-08-14 23:00:00〜2016-08-15 01 :00:00 2016-08-15 23:00:00〜2016-08-16 01:00:00 –

+0

@RameshwarPawale私にとっては明らかではありません。このクエリは期待した結果を示します。何が問題ですか? – NEER

関連する問題