2016-02-20 108 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