Oracle
 sql >> Baza danych >  >> RDS >> Oracle

oblicz godziny na podstawie godzin pracy w Oracle SQL

Możesz bezpośrednio obliczyć różnicę w godzinach:

SELECT task,
       start_time,
       end_time,
       ROUND(
         (
           -- Calculate the full weeks difference from the start of ISO weeks.
           ( TRUNC( end_time, 'IW' ) - TRUNC( start_time, 'IW' ) ) * (10/24) * (6/7)
           -- Add the full days for the final week.
           + LEAST( TRUNC( end_time ) - TRUNC( end_time, 'IW' ), 6 ) * (10/24)
           -- Subtract the full days from the days of the week before the start date.
           - LEAST( TRUNC( start_time ) - TRUNC( start_time, 'IW' ), 6 ) * (10/24)
           -- Add the hours of the final day
           + LEAST( GREATEST( end_time - TRUNC( end_time ) - 8/24, 0 ), 10/24 )
           -- Subtract the hours of the day before the range starts.
           - LEAST( GREATEST( start_time - TRUNC( start_time ) - 8/24, 0 ), 10/24 )
         )
         -- Multiply to give minutes rather than fractions of full days.
         * 24,
         15 -- Number of decimal places
       ) AS work_day_hours_diff
FROM   your_table;

Co dla przykładowych danych:

CREATE TABLE your_table ( TASK, START_TIME, END_TIME ) AS
SELECT 'A', DATE '2017-01-16' + INTERVAL '10:00' HOUR TO MINUTE, DATE '2017-01-23' + INTERVAL '11:35' HOUR TO MINUTE FROM DUAL UNION ALL
SELECT 'B', DATE '2017-01-18' + INTERVAL '17:53' HOUR TO MINUTE, DATE '2017-01-19' + INTERVAL '08:00' HOUR TO MINUTE FROM DUAL UNION ALL
SELECT 'C', DATE '2017-01-13' + INTERVAL '13:00' HOUR TO MINUTE, DATE '2017-01-17' + INTERVAL '14:52' HOUR TO MINUTE FROM DUAL UNION ALL
SELECT 'D', DATE '2017-01-21' + INTERVAL '10:00' HOUR TO MINUTE, DATE '2017-01-30' + INTERVAL '08:52' HOUR TO MINUTE FROM DUAL;

Dane wyjściowe (w formacie daty YYYY-MM-DD HH24:MI:SS (DY) ):

TASK | START_TIME                | END_TIME                  | WORK_DAY_HOURS_DIFF
:--- | :------------------------ | :------------------------ | ------------------:
A    | 2017-01-16 10:00:00 (MON) | 2017-01-23 11:35:00 (MON) |  61.583333333333333
B    | 2017-01-18 17:53:00 (WED) | 2017-01-19 08:00:00 (THU) |    .116666666666667
C    | 2017-01-13 13:00:00 (FRI) | 2017-01-17 14:52:00 (TUE) |  31.866666666666667
D    | 2017-01-21 10:00:00 (SAT) | 2017-01-30 08:52:00 (MON) |  68.866666666666667

db<>graj tutaj

Poprzednie rozwiązanie:

Możesz użyć skorelowanego zapytania hierarchicznego, aby wygenerować jeden wiersz dla każdego dnia roboczego, a następnie zsumować godziny dla każdego dnia:

SELECT task,
       COALESCE( SUM( end_time - start_time ), 0 ) * 24 AS total_hours
FROM   (
  SELECT task,
         GREATEST( t.start_time, d.column_value + INTERVAL '8' HOUR ) AS start_time,
         LEAST( t.end_time, d.column_value + INTERVAL '18' HOUR ) AS end_time
  FROM   your_table t
         LEFT OUTER JOIN
         TABLE(
           CAST(
             MULTISET(
               SELECT TRUNC( t.start_time + LEVEL - 1 )
               FROM   DUAL
               WHERE  TRUNC( t.start_time + LEVEL - 1 ) - TRUNC( t.start_time + LEVEL - 1, 'iw' ) < 6
               CONNECT BY TRUNC( t.start_time + LEVEL - 1 ) < t.end_time
             ) AS SYS.ODCIDATELIST
           )
         ) d
         ON (   t.end_time   > d.column_value + INTERVAL  '8' HOUR
            AND t.start_time < d.column_value + INTERVAL '18' HOUR )
)
GROUP BY task;


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Oracle PL/SQL — zgłaszanie wyjątków zdefiniowanych przez użytkownika za pomocą niestandardowego SQLERRM

  2. MySQL „utwórz schemat” i „utwórz bazę danych” — czy jest jakaś różnica?

  3. Dlaczego otrzymuję java.lang.AbstractMethodError podczas próby załadowania obiektu BLOB do bazy danych?

  4. EBS 12.2.5 i nowsze:Niewspółosiowość przycisku strony logowania

  5. ORA-12519 TNS:nie znaleziono odpowiedniej obsługi serwisowej