2016-02-20 68 views
1

需要你的幫助來完成這個刪除重疊小時

二月具有完全696小時

 Start Date  End Date 
S1 - 01-Feb-16 04:00 - 02-Feb-16 10:00 - 30hrs 
S2 - 02-Feb-16 14:00 - 06-Feb-16 20:00 - 102hrs 
S3 - 01-Feb-16 01:00 - 02-Feb-16 07:00 - 30hrs 

       Total Worked hrs - 162 hrs 

由於有27個小時,可重疊S1和S3,所以總工作小時 - 135個小時 預期的查詢結果是561個小時

我有一個挑戰,在這裏與代碼 1碼準備這確實另一部分除了忽略的重疊時間,需要你的幫助。 2.如何限制查詢,以驗證只爲SYSDATE月

Query: 
SELECT (ADD_MONTHS(TRUNC(SYSDATE, 'MM'), 1) - TRUNC(SYSDATE, 'MM') 
     - SUM(End_Date - Start_Date)) * 24 AS Unworked_Hours 
FROM Trip_Dates; 

回答

1

甲骨文設置

CREATE TABLE Trip_Dates (Start_Date, End_Date) AS 
SELECT TO_DATE('2016-02-01 04:00:00', 'YYYY-MM-DD HH24:MI:SS'), TO_DATE('2016-02-02 10:00:00', 'YYYY-MM-DD HH24:MI:SS') FROM DUAL UNION ALL 
SELECT TO_DATE('2016-02-02 14:00:00', 'YYYY-MM-DD HH24:MI:SS'), TO_DATE('2016-02-06 20:00:00', 'YYYY-MM-DD HH24:MI:SS') FROM DUAL UNION ALL 
SELECT TO_DATE('2016-02-01 01:00:00', 'YYYY-MM-DD HH24:MI:SS'), TO_DATE('2016-02-02 07:00:00', 'YYYY-MM-DD HH24:MI:SS') FROM DUAL; 

查詢

WITH Dates (dt, start_end) AS (
    SELECT GREATEST(start_date, TRUNC(SYSDATE, 'MM')), 
     1 
    FROM trip_dates 
    WHERE start_date < ADD_MONTHS(TRUNC(SYSDATE, 'MM'), 1) 
    AND end_date > TRUNC(SYSDATE, 'MM') 
    UNION ALL 
    SELECT LEAST(end_date, ADD_MONTHS(TRUNC(SYSDATE, 'MM'), 1)), 
     -1 
    FROM trip_dates 
    WHERE start_date < ADD_MONTHS(TRUNC(SYSDATE, 'MM'), 1) 
    AND end_date > TRUNC(SYSDATE, 'MM') 
    ORDER BY 1, 2 
) 
,range_start_ends (dt, start_end, range_start, range_end) AS (
    SELECT d.*, 
     CASE 
      WHEN start_end = 1 
      AND SUM(start_end) OVER (ORDER BY dt) = 1 
      THEN dt 
      ELSE NULL 
      END, 
     CASE 
      WHEN start_end = -1 
      AND SUM(start_end) OVER (ORDER BY dt) = 0 
      THEN dt 
      ELSE NULL 
      END 
    FROM Dates d 
), 
worked_days (worked_days) AS (
    SELECT range_end - LAG(range_start) IGNORE NULLS OVER (ORDER BY dt) 
    FROM range_start_ends 
) 
SELECT (ADD_MONTHS(TRUNC(SYSDATE, 'MM'), 1) 
     - TRUNC(SYSDATE, 'MM') - 
     SUM(worked_days) 
     ) * 24 AS unworked_hours 
FROM worked_days; 

結果

UNWORKED_HOURS 
-------------- 
      561