Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

tính toán giờ dựa trên giờ làm việc trong Oracle SQL

Bạn có thể tính trực tiếp chênh lệch theo giờ:

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;

Cái nào, dành cho dữ liệu mẫu của bạn:

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;

Kết quả đầu ra (với định dạng ngày tháng 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 <> fiddle here

Giải pháp trước:

Bạn có thể sử dụng truy vấn phân cấp tương quan để tạo một hàng cho mỗi ngày làm việc và sau đó tính tổng số giờ cho mỗi ngày:

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. OLAP mô phỏng

  2. Làm thế nào để tìm sự khác biệt b / w các giá trị định dạng TIMESTAMP trong Oracle?

  3. Trục động trong sql oracle

  4. Cách tránh lỗi đột biến bảng

  5. Bảng kiểm tra Oracle Trigger cơ bản