2017-08-01 62 views
0

我試圖在上午8點和下午6點之間的時間表中查找時差。我能夠找到記錄記錄的差距,但我無法弄清楚如何確定記錄是否「錯過」 - 意味着如果記錄是在上午8:30開始的,我無法弄清楚如何識別30分鐘的差距上午8點到8點30分(即他們開始工作到很晚)。在特定時間內查找時間表數據中的空白

在下面例子中,我可以找到關於5/8 12和下午12:30,而不是8 am-8:30am間隙和5:30之間的兩個間隙到下午6點的間隙,和8 am-8:30am間隙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

我不認爲他會工作@ m84作爲開始時間可以是上午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

謝謝安德烈,那非常接近,這種時間條目''2017-05-08 06:30:00.000','2017-05-08 08:30:00.000''雖然沒有被正確處理。在這裏,員工的工作時間是上午8點到上午8點30分,但上面的查詢顯示上午8點到上午8點30分有差距。 – Greg

+0

@Greg,你能添加一個預期的輸出嗎?提前致謝。 –

相關問題