Oracle
 sql >> база данни >  >> RDS >> Oracle

Изчислете времевата разлика в SQL със смени

Използвайте клауза за факторизиране на рекурсивна подзаявка, за да генерирате всеки ден в рамките на вашите времеви диапазони и след това да го свържете с вашите смени, за да ограничите времето за всеки ден да бъде в рамките на часовете на смяната и след това обобщете, за да получите общата сума:

Настройка на Oracle 18 :

CREATE TABLE times ( start_date, End_Date ) AS
SELECT DATE '2017-02-21' + INTERVAL '07:52:32' HOUR TO SECOND,
       DATE '2017-02-22' + INTERVAL '09:56:32' HOUR TO SECOND
FROM   DUAL
UNION ALL
SELECT DATE '2017-02-21' + INTERVAL '09:52:32' HOUR TO SECOND,
       DATE '2017-02-23' + INTERVAL '17:52:32' HOUR TO SECOND
FROM   DUAL;

CREATE TABLE weekly_shifts ( shift_day, Start_Time, End_Time ) AS
SELECT 'MON', INTERVAL '09:00' HOUR TO MINUTE, INTERVAL '18:00' HOUR TO MINUTE FROM DUAL UNION ALL
SELECT 'TUE', INTERVAL '10:00' HOUR TO MINUTE, INTERVAL '19:00' HOUR TO MINUTE FROM DUAL UNION ALL
SELECT 'WED', INTERVAL '09:00' HOUR TO MINUTE, INTERVAL '18:00' HOUR TO MINUTE FROM DUAL UNION ALL
SELECT 'THU', INTERVAL '10:00' HOUR TO MINUTE, INTERVAL '19:00' HOUR TO MINUTE FROM DUAL UNION ALL
SELECT 'FRI', INTERVAL '09:00' HOUR TO MINUTE, INTERVAL '18:00' HOUR TO MINUTE FROM DUAL;

Заявка 1 :

WITH days ( id, start_date, day_start, day_end, end_date ) AS (
  SELECT ROWNUM,
         start_date,
         start_date,
         LEAST( TRUNC( start_date ) + INTERVAL '1' DAY, end_date ),
         end_date
  FROM   times
UNION ALL
  SELECT id,
         start_date,
         day_end,
         LEAST( day_end + INTERVAL '1' DAY, end_date ),
         end_date
  FROM   days
  WHERE  day_end < end_date
)
SELECT start_date,
       end_date,
       SUM( shift_end - shift_start ) AS days_worked_on_shift
FROM   (
  SELECT ID,
         start_date,
         end_date,
         GREATEST( day_start, TRUNC( day_start ) + start_time ) AS shift_start,
         LEAST( day_end, TRUNC( day_start ) + end_time ) AS shift_end
  FROM   days d
         INNER JOIN
         weekly_shifts w
         ON ( TO_CHAR( d.day_start, 'DY' ) = w.shift_day )
)
GROUP BY id, start_date, end_date;

Резултат :

START_DATE          END_DATE            DAYS_WORKED_ON_SHIFT
------------------- ------------------- --------------------
2017-02-21 07:52:32 2017-02-22 09:56:32 0.414259259259259259
2017-02-21 09:52:32 2017-02-23 17:52:32 1.078148148148148148



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Кога трябва да използвам Index Organized Table на Oracle? Или кога не трябва?

  2. Как да напиша заявка, която прави нещо подобно на GROUP_CONCAT на MySQL в Oracle?

  3. получаване на грешка, аргументът '0' е извън диапазона

  4. Грешка в DYLD_LIBRARY_PATH в моменталния клиент на Oracle

  5. Задаване на часова зона на сесията с spring jdbc oracle