2017-08-01 8 views
0

私は午前8時から午後6時の間のタイムシートの隙間を見つけようとしています。記録されているレコードのギャップを見つけることができますが、レコードが「逃した」かどうかを判断する方法がわかりません。つまり、午前8時30分に開始した場合、30分のギャップを特定する方法はわかりません午前8時から午前8時30分まで(すなわち、彼らは遅く仕事を始めた)。特定の時間のタイムシートデータのギャップを見つける

以下の例では、午前12時から午後12時30分までの間に2つのギャップがありますが、5/8の午前8時〜8時30分と5時30分〜 5/10。

私はこれにどのようにアプローチできるかについて正しい方向で私を指摘するアイデアはありますか?

drop table #time; 
create table #time (
    TimesheetId int not null 
    , StartTime datetime not null 
    , EndTIme datetime not null 
); 

insert into #time (TimesheetId, StartTime, EndTime) 
    values (210, '2017-05-08 05:30:00.000', '2017-05-08 06:30:00.000') 
     , (210, '2017-05-08 06:30:00.000', '2017-05-08 08:30:00.000') 
     , (210, '2017-05-08 08:30:00.000', '2017-05-08 12:00:00.000') 
     , (210, '2017-05-08 12:30:00.000', '2017-05-08 18:30:00.000') 
     , (210, '2017-05-09 08:30:00.000', '2017-05-09 12:00:00.000') 
     , (210, '2017-05-09 12:30:00.000', '2017-05-09 17:30:00.000') 
     , (210, '2017-05-09 22:30:00.000', '2017-05-10 05:30:00.000') 
     , (210, '2017-05-10 08:30:00.000', '2017-05-10 18:00:00.000') 
; 

; with t1 as (
    SELECT TimesheetId 
     , StartTime 
     , lag(EndTime) OVER (PARTITION BY TimesheetId ORDER BY StartTime) AS prev_endtime 
    FROM #time 
    where datepart(HH, StartTime) <= 18 
     and datepart(HH, EndTime) >= 8 
) 
select prev_endtime as gapStart 
    , StartTime as gapEnd 
from t1 
where StartTime <> prev_endtime 
and cast(prev_endtime as date) = cast(StartTime as date) 
; 
+0

あなたは「AND datepart(MM、startTime)<> 00」と「EndTime」と同じものを追加することができます – M84

+0

開始時刻が午前7時30分になり、終了時刻が後になると思います午前8時です。 05/08の – Greg

+1

、これはどうですか? (210、 '2017-05-08 06:30:00.000'、 '2017-05-08 08:30:00.000')期待した結果セットを使って質問を更新できますか? – CuriousKid

答えて

0

あなたはレコードを挿入するためにこれを使用して、あなたが
それとも、UNIONを使用することができ

select distinct t1.TimesheetId, dateadd(hh, 8, cast(CONVERT(date, StartTime) as datetime)) as StartTime, dateadd(hh, 8, cast(CONVERT(date, StartTime) as datetime)) as EndTime 
    from #time t1 
where not exists (select dateadd(hh, 8, cast(CONVERT(date, T2.StartTime) as datetime)), t2.* 
        from #time T2 
        where 1 = 1 
         and t2.TimesheetId = t1.TimesheetId 
         and CONVERT(date, T2.StartTime) = CONVERT(date, T1.StartTime) 
         and t2.StartTime = dateadd(hh, 8, cast(CONVERT(date, t2.StartTime) as datetime)) 
       ) 
2
WITH 
    a AS(SELECT DATEADD(hh, DATEDIFF(dd, 0, StartTime) * 24 + 8, 0) t, 
     TimesheetId FROM #time), 
    b AS(SELECT * FROM #time UNION ALL SELECT TimesheetId, t, t FROM a UNION ALL 
     SELECT TimesheetId, DATEADD(hh, 10, t), DATEADD(hh, 10, t) FROM a), 
    c AS(SELECT TimesheetId, 
     LAG(EndTime) OVER (
      PARTITION BY TimesheetId ORDER BY StartTime 
     ) prev_fin, 
     StartTime 
     FROM b), 
    d AS(SELECT *, DATEADD(hh, DATEDIFF(dd, 0, prev_fin) * 24 + 8, 0) beg, 
      DATEADD(hh, DATEDIFF(dd, 0, prev_fin) * 24 + 18, 0) fin 
     FROM c) 
SELECT TimesheetId, prev_fin, StartTime 
FROM d 
WHERE prev_fin < StartTime AND 
    ((prev_fin >= beg AND prev_fin < fin) OR 
    (StartTime > beg AND StartTime <= fin)); 

持っているものを使用することができますrextester.comでそれを確認してください。

+0

ありがとうございましたAndrei、これは非常に近いですが、この種のタイムエントリ「2017-05-08 06:30:00.000」、「2017-05-08 08:30:00.000」は正しく処理されていません。ここでは、従業員は午前8時から午前8時30分まで働いていましたが、上のクエリは午前8時から午前8時30分までのギャップを示しています。 – Greg

+0

@Greg、予想される出力を追加できますか?前もって感謝します。 –

関連する問題