Calculating passed service hours for open tickets (Oracle SQL)

孤人 提交于 2021-01-28 11:27:46

问题


I'm trying to calculate the time that has passed since a service request has been logged (service time), based on service hours.

Start time is the time the ticket has been logged (date_logged), end time would be either the current time for open tickets or the date_closed for closed tickets.

Service hours are:

  • Monday to Thursday 07:00 - 16:30
  • Friday 07:00 - 13:00

So it should look something like this (minus the "current datetime" column, that's just for context):

Ticket-Nr. date_logged service time [hh:mm] current datetime date_closed
1234567 06.01.21 11:30:52 62:33 14.01.2021 12:03
8912345 13.01.21 09:14:16 12:19 14.01.2021 12:03
6789012 14.01.21 10:48:01 00:28 14.01.2021 12:03 14.01.21 11:40
... ... ... ... ...

I can't say yet whether public holidays have to be included or not, so we can ignore those for now.

I'm thankful for any help whatsoever!


回答1:


You can calculate the amount of time (adapted from my answers here and here):

SELECT ticket_nr,
       date_logged,
       current_datetime,
       date_closed,
       TO_CHAR( FLOOR( service_time_seconds / 60 / 60 ), 'FM9990' )
       || ':'
       || TO_CHAR( MOD( FLOOR( service_time_seconds / 60 ), 60 ), 'FM00' )
       || ':'
       || TO_CHAR( MOD( service_time_seconds, 60 ), 'FM00' )
         AS "SERVICE_TIME HH:MM:SS"
FROM   (
SELECT ticket_nr,
       date_logged,
       SYSDATE AS current_datetime,
       date_closed,
       ROUND(
         (
           -- Calculate the full weeks difference from the start of ISO weeks.
           ( 
             TRUNC( COALESCE( date_closed, SYSDATE ), 'IW' )
             - TRUNC( date_logged, 'IW' )
           ) * (9.5*4+6)/(7*24)
           -- Add the hours for the full days for the final week.
           + DECODE(
               TRUNC( COALESCE( date_closed, SYSDATE ) )
               - TRUNC( COALESCE( date_closed, SYSDATE ), 'IW' ),
               0,  0.0,
               1,  9.5,
               2, 19.0,
               3, 28.5,
               4, 38.0,
                  44.0
             ) / 24
           -- Subtract the hours for the full days from the days of the week
           -- before the date logged.
           - DECODE(
               TRUNC( date_logged )
               - TRUNC( date_logged, 'IW' ),
               0,  0.0,
               1,  9.5,
               2, 19.0,
               3, 28.5,
               4, 38.0,
                  44.0
             ) / 24
           -- Add the hours of the final day
           + LEAST(
               GREATEST(
                 COALESCE( date_closed, SYSDATE )
                 - ( TRUNC( COALESCE( date_closed, SYSDATE ) )
                     + INTERVAL '07:00' HOUR TO MINUTE
                   ),
                 0
               ),
               DECODE(
                 TRUNC( COALESCE( date_closed, SYSDATE ) )
                 - TRUNC( COALESCE( date_closed, SYSDATE ), 'IW' ),
                 0, 9.5,
                 1, 9.5,
                 2, 9.5,
                 3, 9.5,
                 4, 6.0,
                    0.0
               ) / 24
             )
           -- Subtract the hours of the day before the range starts.
           - LEAST(
               GREATEST(
                 date_logged
                 - ( TRUNC( date_logged ) + INTERVAL '07:00' HOUR TO MINUTE ),
                 0
               ),
               DECODE(
                 TRUNC( date_logged )
                 - TRUNC( date_logged, 'IW' ),
                 0, 9.5,
                 1, 9.5,
                 2, 9.5,
                 3, 9.5,
                 4, 6.0,
                    0.0
               ) / 24
             )
         )
         -- Multiply to give seconds rather than fractions of full days.
         * 24 * 60 * 60
       ) AS service_time_seconds
FROM   table_name
);

Which, for the sample data:

CREATE TABLE table_name ( Ticket_Nr, date_logged, date_closed ) AS
SELECT 1234567, DATE '2021-01-06' + INTERVAL '11:30:52' HOUR TO SECOND, NULL FROM DUAL UNION ALL
SELECT 8912345, DATE '2021-01-13' + INTERVAL '09:14:16' HOUR TO SECOND, NULL FROM DUAL UNION ALL
SELECT 6789012, DATE '2021-01-14' + INTERVAL '10:48:28' HOUR TO SECOND, DATE '2021-01-21' + INTERVAL '11:40:00' HOUR TO SECOND FROM DUAL UNION ALL
SELECT       1, DATE '2021-01-07' + INTERVAL '07:00:00' HOUR TO SECOND, DATE '2021-01-14' + INTERVAL '07:00:00' HOUR TO SECOND FROM DUAL UNION ALL
SELECT       2, DATE '2021-01-07' + INTERVAL '07:00:00' HOUR TO SECOND, DATE '2021-01-08' + INTERVAL '07:00:00' HOUR TO SECOND FROM DUAL UNION ALL
SELECT       3, DATE '2021-01-08' + INTERVAL '07:00:00' HOUR TO SECOND, DATE '2021-01-09' + INTERVAL '07:00:00' HOUR TO SECOND FROM DUAL UNION ALL
SELECT       4, DATE '2021-01-09' + INTERVAL '07:00:00' HOUR TO SECOND, DATE '2021-01-10' + INTERVAL '07:00:00' HOUR TO SECOND FROM DUAL

Outputs (where NLS_DATE_FORMAT is YYYY-MM-DD HH24:MI:SS (DY)):

TICKET_NR | DATE_LOGGED               | CURRENT_DATETIME          | DATE_CLOSED               | SERVICE_TIME HH:MM:SS
--------: | :------------------------ | :------------------------ | :------------------------ | :--------------------
  1234567 | 2021-01-06 11:30:52 (WED) | 2021-01-14 12:36:54 (THU) | null                      | 54:36:02             
  8912345 | 2021-01-13 09:14:16 (WED) | 2021-01-14 12:36:54 (THU) | null                      | 12:52:38             
  6789012 | 2021-01-14 10:48:28 (THU) | 2021-01-14 12:36:54 (THU) | 2021-01-21 11:40:00 (THU) | 44:51:32             
        1 | 2021-01-07 07:00:00 (THU) | 2021-01-14 12:36:54 (THU) | 2021-01-14 07:00:00 (THU) | 44:00:00             
        2 | 2021-01-07 07:00:00 (THU) | 2021-01-14 12:36:54 (THU) | 2021-01-08 07:00:00 (FRI) | 9:30:00              
        3 | 2021-01-08 07:00:00 (FRI) | 2021-01-14 12:36:54 (THU) | 2021-01-09 07:00:00 (SAT) | 6:00:00              
        4 | 2021-01-09 07:00:00 (SAT) | 2021-01-14 12:36:54 (THU) | 2021-01-10 07:00:00 (SUN) | 0:00:00              

db<>fiddle here



来源:https://stackoverflow.com/questions/65717847/calculating-passed-service-hours-for-open-tickets-oracle-sql

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!