簡體   English   中英

根據營業時間而不是總時間計算處理時間

[英]Calculating processing time based on business hours instead of total hours

我正在嘗試計算自記錄票以來經過的服務時間。 當票證被記錄時,時間戳會隨之保存( date_logged )。 當它關閉時,會保存另一個時間戳( date_closed )。

需要

我需要的是根據分配給工單的部門的服務時間,在 date_logged 和當前 datetime 之間經過的時間(對於打開的工單)或 date_logged 和 date_close 之間的時間(對於關閉的工單)。

公共假期必須包括在內。

現有表

指定部門的服務時間與工單保存在同一個表中。 該表如下所示:

事件參考 date_logged 日期關閉 sla_mon_start sla_mon_end sla_tue_start sla_tue_end sla_wed_start sla_wed_end sla_thr_start sla_thr_end sla_fri_start sla_fri_end sla_sat_start sla_sat_end sla_sun_start sla_sun_end
1660565 一個 06.01.21 11:30:52 01.01.01 07:30:00 01.01.01 16:45:00 01.01.01 07:30:00 01.01.01 16:45 01.01.01 07:30:00 01.01.01 16:45:00 01.01.01 07:30:00 01.01.01 16:45:00 01.01.01 07:30:00 01.01.01 13:00:00 01.01.01 00:00:00 01.01.01 00:00:00 01.01.01 00:00:00 01.01.01 00:00:00
1660567 13.01.21 09:14:16 01.01.01 07:00:00 01.01.01 16:30:00 01.01.01 07:00:00 01.01.01 16:30:00 01.01.01 07:00:00 01.01.01 16:30:00 01.01.01 07:00:00 01.01.01 16:30:00 01.01.01 07:00:00 01.01.01 16:30:00 01.01.01 07:00:00 01.01.01 15:00:00 01.01.01 00:00:00 01.01.01 00:00:00
1660558 C 31.12.20 07:04:46 31.12.20 07:36:59 01.01.01 07:00:00 01.01.01 16:30:00 01.01.01 07:00:00 01.01.01 16:30:00 01.01.01 07:00:00 01.01.01 16:30:00 01.01.01 07:00:00 01.01.01 16:30:00 01.01.01 07:00:00 01.01.01 16:30:00 01.01.01 07:00:00 01.01.01 15:00:00 01.01.01 00:00:00 01.01.01 00:00:00
3456789 D 01.01.21 09:41:00 04.01.21 08:21:00 01.01.01 08:00:00 01.01.01 15:00:00 01.01.01 08:00:00 01.01.01 15:00:00 01.01.01 08:00:00 01.01.01 15:00:00 01.01.01 08:00:00 01.01.01 15:00:00 01.01.01 08:00:00 01.01.01 13:00:00 01.01.01 00:00:00 01.01.01 00:00:00 01.01.01 00:00:00 01.01.01 00:00:00
0123456 D 02.01.21 13:12:00 ... ... ... ... ...

我只有讀取這個數據庫的權限,所以我不能更改現有表或創建新表。

我試過的

根據我對上一個問題的回答,我嘗試如下所示解決它,但這樣我只會收到錯誤“日期+日期不允許”。 我還沒有嘗試包括公共假期,因為 rest 已經不起作用了。

SELECT incident_ref,
       date_logged,
       Inc_close_date,
       TO_CHAR( FLOOR( service_time_seconds / 60 / 60 ), 'FM99990' )
       || ':'
       || TO_CHAR( MOD( FLOOR( service_time_seconds / 60 ), 60 ), 'FM00' )
       || ':'
       || TO_CHAR( MOD( service_time_seconds, 60 ), 'FM00' )
         AS "service time [hh:mm]"
FROM   (
SELECT inc.incident_ref,
       inc.date_logged,
       inc.Inc_close_date,
       ROUND(
         (
           -- Calculate the full weeks difference from the start of ISO weeks.
           ( 
             TRUNC( COALESCE( Inc_close_date, SYSDATE ), 'IW' )
             - TRUNC( date_logged, 'IW' )
           ) * ( (24*(sla_mon_end-sla_mon_start))
                 + (24*(sla_tue_end-sla_tue_start))
                 + (24*(sla_wed_end-sla_wed_start))
                 + (24*(sla_thr_end-sla_thr_start))
                 + (24*(sla_fri_end-sla_fri_start))
                 + (24*(sla_sat_end-sla_sat_start))
                 + (24*(sla_sun_end-sla_sun_start) )) / (7*24)
           -- Add the hours for the full days for the final week.
           + DECODE(
               TRUNC( COALESCE( Inc_close_date, SYSDATE ) )
               - TRUNC( COALESCE( Inc_close_date, SYSDATE ), 'IW' ),
               0,  0.0,
               1, (24*(sla_mon_end-sla_mon_start)),
               2, (24*(sla_mon_end-sla_mon_start)) + 24*(sla_wed_end-sla_tue_start),
               3, (24*(sla_mon_end-sla_mon_start)) + 24*(sla_wed_end-sla_tue_start) + 24*(sla_wed_end-sla_wed_start),
               4, (24*(sla_mon_end-sla_mon_start)) + 24*(sla_wed_end-sla_tue_start) + 24*(sla_wed_end-sla_wed_start) + 24*(sla_thr_end-sla_thr_start),
               5, (24*(sla_mon_end-sla_mon_start)) + 24*(sla_wed_end-sla_tue_start) + 24*(sla_wed_end-sla_wed_start) + 24*(sla_thr_end-sla_thr_start) + 24*(sla_fri_end-sla_fri_start),
               6, (24*(sla_mon_end-sla_mon_start)) + 24*(sla_wed_end-sla_tue_start) + 24*(sla_wed_end-sla_wed_start) + 24*(sla_thr_end-sla_thr_start) + 24*(sla_fri_end-sla_fri_start) + 24*(sla_sat_end-sla_sat_start)
             ) / 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, 24*(sla_mon_end-sla_mon_start),
               2, 24*(sla_mon_end-sla_mon_start) + 24*(sla_wed_end-sla_tue_start),
               3, 24*(sla_mon_end-sla_mon_start) + 24*(sla_wed_end-sla_tue_start) + 24*(sla_wed_end-sla_wed_start),
               4, 24*(sla_mon_end-sla_mon_start) + 24*(sla_wed_end-sla_tue_start) + 24*(sla_wed_end-sla_wed_start) + 24*(sla_thr_end-sla_thr_start),
               5, 24*(sla_mon_end-sla_mon_start) + 24*(sla_wed_end-sla_tue_start) + 24*(sla_wed_end-sla_wed_start) + 24*(sla_thr_end-sla_thr_start) + 24*(sla_fri_end-sla_fri_start),
               6, 24*(sla_mon_end-sla_mon_start) + 24*(sla_wed_end-sla_tue_start) + 24*(sla_wed_end-sla_wed_start) + 24*(sla_thr_end-sla_thr_start) + 24*(sla_fri_end-sla_fri_start) + 24*(sla_sat_end-sla_sat_start)
             ) / 24
           -- Add the hours of the final day
           + COALESCE(
               GREATEST(
                 LEAST(
                   COALESCE( Inc_close_date, SYSDATE ),
                   TRUNC( COALESCE( Inc_close_date, SYSDATE ) )
                   + DECODE(
                       TRUNC( COALESCE( Inc_close_date, SYSDATE ) )
                       - TRUNC( COALESCE( Inc_close_date, SYSDATE ), 'IW' ),
                       0, sla_mon_end,
                       1, sla_tue_end,
                       2, sla_wed_end,
                       3, sla_thr_end,
                       4, sla_fri_end,
                       5, sla_sat_end,
                       6, sla_sun_end
                     )
                 )
                 -
                 (
                   TRUNC( COALESCE( Inc_close_date, SYSDATE ) )
                   + DECODE(
                       TRUNC( COALESCE( Inc_close_date, SYSDATE ) )
                       - TRUNC( COALESCE( Inc_close_date, SYSDATE ), 'IW' ),
                       0, sla_mon_start,
                       1, sla_tue_start,
                       2, sla_wed_start,
                       3, sla_thr_start,
                       4, sla_fri_start,
                       5, sla_sat_start,
                       6, sla_sun_start
                     )
                   ),
                 0
               ) / 24,
               0
             )
           -- Subtract the hours of the day before the range starts.
           + COALESCE(
               GREATEST(
                 LEAST(
                   date_logged,
                   date_logged
                   + DECODE(
                       TRUNC( COALESCE( Inc_close_date, SYSDATE ) )
                       - TRUNC( COALESCE( Inc_close_date, SYSDATE ), 'IW' ),
                       0, sla_mon_end,
                       1, sla_tue_end,
                       2, sla_wed_end,
                       3, sla_thr_end,
                       4, sla_fri_end,
                       5, sla_sat_end,
                       6, sla_sun_end
                     )
                 )
                 -
                 (
                   date_logged
                   + DECODE(
                       TRUNC( COALESCE( Inc_close_date, SYSDATE ) )
                       - TRUNC( COALESCE( Inc_close_date, SYSDATE ), 'IW' ),
                       0, sla_mon_start,
                       1, sla_tue_start,
                       2, sla_wed_start,
                       3, sla_thr_start,
                       4, sla_fri_start,
                       5, sla_sat_start,
                       6, sla_sun_start
                     )
                   ),
                 0
               ) / 24,
               0
             )
         )
         -- Multiply to give seconds rather than fractions of full days.
         * 24 * 60 * 60
       ) AS service_time_seconds
FROM   incident inc
);

預期成績

(門票與上表相同,如果您想了解部門,當前日期時間列僅供參考,實際結果中不需要)

事件參考 date_logged 日期關閉 服務時間 [hh:mm] 當前日期時間
1660565 31.12.20 07:15:48 131:54 22.01.2021 10:09
1660567 31.12.20 07:17:56 160:21 22.01.2021 10:09
1660558 31.12.20 07:04:46 31.12.20 07:36:59 00:32 22.01.2021 10:09
3456789 01.01.21 09:41:00 04.01.21 08:21:00 00:21 22.01.2021 10:09

通過最后一張票,您可以看到分配的部門在新年沒有工作。

也許這會有所幫助:

WITH
    sample AS       -- sample data with DATE_CLOSED defined
        (
            SELECT DISTINCT
                INCIDENT_REF,
                DEPARTMENT, SLA_MON_START, SLA_MON_END,  SLA_TUE_START, SLA_TUE_END,  SLA_WED_START, SLA_WED_END,  SLA_THR_START, SLA_THR_END,  SLA_FRI_START, SLA_FRI_END,  SLA_SAT_START, SLA_SAT_END,  SLA_SUN_START, SLA_SUN_END,
                DATE_LOGGED,
                To_Char(DATE_LOGGED, 'hh:mi') "TIME_LOGGED",
                Nvl(DATE_CLOSED, To_Date('01.22.2021 10:09', 'mm.dd.yyyy hh24:mi')) "DATE_CLOSED", 
                To_Char(Nvl(DATE_CLOSED, To_Date('01.22.2021 10:09', 'mm.dd.yyyy hh24:mi')), 'hh:mi') "TIME_CLOSED"
            FROM
                SAMPLEDATA s
        ),
    days AS         -- generate all the missing dates with the service hours depending on a day of week - calculate effective service time (hours) by date
        (
            SELECT DISTINCT 
                INCIDENT_REF "INCIDENT_REF",
                DEPARTMENT "DEPARTMENT",
                DATE_LOGGED "DATE_LOGGED",
                DATE_LOGGED + LEVEL - 1 "WRK_DATE",
                CASE
                    WHEN To_Char(DATE_LOGGED  + LEVEL - 1, 'd') = '1' THEN To_Char(SLA_MON_START, 'hh24:mi') || '-' || To_Char(SLA_MON_END, 'hh24:mi')  
                    WHEN To_Char(DATE_LOGGED  + LEVEL - 1, 'd') = '2' THEN To_Char(SLA_TUE_START, 'hh24:mi') || '-' || To_Char(SLA_TUE_END, 'hh24:mi') 
                    WHEN To_Char(DATE_LOGGED  + LEVEL - 1, 'd') = '3' THEN To_Char(SLA_WED_START, 'hh24:mi') || '-' || To_Char(SLA_WED_END, 'hh24:mi') 
                    WHEN To_Char(DATE_LOGGED  + LEVEL - 1, 'd') = '4' THEN To_Char(SLA_THR_START, 'hh24:mi') || '-' || To_Char(SLA_THR_END, 'hh24:mi') 
                    WHEN To_Char(DATE_LOGGED  + LEVEL - 1, 'd') = '5' THEN To_Char(SLA_FRI_START, 'hh24:mi') || '-' || To_Char(SLA_FRI_END, 'hh24:mi') 
                    WHEN To_Char(DATE_LOGGED  + LEVEL - 1, 'd') = '6' THEN To_Char(SLA_SAT_START, 'hh24:mi') || '-' || To_Char(SLA_SAT_END, 'hh24:mi') 
                    WHEN To_Char(DATE_LOGGED  + LEVEL - 1, 'd') = '7' THEN To_Char(SLA_SUN_START, 'hh24:mi') || '-' || To_Char(SLA_SUN_END, 'hh24:mi') 
                END "SERVICE_HOURS_SPAN",
                --
               CASE
                    WHEN To_Char(DATE_LOGGED  + LEVEL - 1, 'd') = '1' THEN (SLA_MON_END - SLA_MON_START) * 24  
                    WHEN To_Char(DATE_LOGGED  + LEVEL - 1, 'd') = '2' THEN (SLA_TUE_END - SLA_TUE_START) * 24  
                    WHEN To_Char(DATE_LOGGED  + LEVEL - 1, 'd') = '3' THEN (SLA_WED_END - SLA_WED_START) * 24  
                    WHEN To_Char(DATE_LOGGED  + LEVEL - 1, 'd') = '4' THEN (SLA_THR_END - SLA_THR_START) * 24  
                    WHEN To_Char(DATE_LOGGED  + LEVEL - 1, 'd') = '5' THEN (SLA_FRI_END - SLA_FRI_START) * 24  
                    WHEN To_Char(DATE_LOGGED  + LEVEL - 1, 'd') = '6' THEN (SLA_SAT_END - SLA_SAT_START) * 24  
                    WHEN To_Char(DATE_LOGGED  + LEVEL - 1, 'd') = '7' THEN (SLA_SUN_END - SLA_SUN_START) * 24  
                END "SCHEDULED_SERVICE_HOURS",
              --
               CASE
                    WHEN TRUNC(DATE_LOGGED, 'dd') = TRUNC(DATE_LOGGED  + LEVEL - 1, 'dd') And To_Char(DATE_LOGGED  + LEVEL - 1, 'd') = '1' And TRUNC(DATE_LOGGED, 'dd') <> TRUNC(Nvl(DATE_CLOSED, To_Date('01.22.2021', 'mm.dd.yyyy')), 'dd') THEN (SLA_MON_END - To_Date(To_Char(SLA_MON_END, 'mm.dd.yyyy') || ' ' || TIME_LOGGED, 'mm.dd.yyyy hh24:mi')) * 24  
                    WHEN TRUNC(DATE_LOGGED, 'dd') = TRUNC(DATE_LOGGED  + LEVEL - 1, 'dd') And To_Char(DATE_LOGGED  + LEVEL - 1, 'd') = '2' And TRUNC(DATE_LOGGED, 'dd') <> TRUNC(Nvl(DATE_CLOSED, To_Date('01.22.2021', 'mm.dd.yyyy')), 'dd') THEN (SLA_TUE_END - To_Date(To_Char(SLA_TUE_END, 'mm.dd.yyyy') || ' ' || TIME_LOGGED, 'mm.dd.yyyy hh24:mi')) * 24  
                    WHEN TRUNC(DATE_LOGGED, 'dd') = TRUNC(DATE_LOGGED  + LEVEL - 1, 'dd') And To_Char(DATE_LOGGED  + LEVEL - 1, 'd') = '3' And TRUNC(DATE_LOGGED, 'dd') <> TRUNC(Nvl(DATE_CLOSED, To_Date('01.22.2021', 'mm.dd.yyyy')), 'dd') THEN (SLA_WED_END - To_Date(To_Char(SLA_WED_END, 'mm.dd.yyyy') || ' ' || TIME_LOGGED, 'mm.dd.yyyy hh24:mi')) * 24  
                    WHEN TRUNC(DATE_LOGGED, 'dd') = TRUNC(DATE_LOGGED  + LEVEL - 1, 'dd') And To_Char(DATE_LOGGED  + LEVEL - 1, 'd') = '4' And TRUNC(DATE_LOGGED, 'dd') <> TRUNC(Nvl(DATE_CLOSED, To_Date('01.22.2021', 'mm.dd.yyyy')), 'dd') THEN (SLA_THR_END - To_Date(To_Char(SLA_THR_END, 'mm.dd.yyyy') || ' ' || TIME_LOGGED, 'mm.dd.yyyy hh24:mi')) * 24  
                    WHEN TRUNC(DATE_LOGGED, 'dd') = TRUNC(DATE_LOGGED  + LEVEL - 1, 'dd') And To_Char(DATE_LOGGED  + LEVEL - 1, 'd') = '5' And TRUNC(DATE_LOGGED, 'dd') <> TRUNC(Nvl(DATE_CLOSED, To_Date('01.22.2021', 'mm.dd.yyyy')), 'dd') THEN (SLA_FRI_END - To_Date(To_Char(SLA_FRI_END, 'mm.dd.yyyy') || ' ' || TIME_LOGGED, 'mm.dd.yyyy hh24:mi')) * 24  
                    WHEN TRUNC(DATE_LOGGED, 'dd') = TRUNC(DATE_LOGGED  + LEVEL - 1, 'dd') And To_Char(DATE_LOGGED  + LEVEL - 1, 'd') = '6' And TRUNC(DATE_LOGGED, 'dd') <> TRUNC(Nvl(DATE_CLOSED, To_Date('01.22.2021', 'mm.dd.yyyy')), 'dd') THEN (SLA_SAT_END - To_Date(To_Char(SLA_SAT_END, 'mm.dd.yyyy') || ' ' || TIME_LOGGED, 'mm.dd.yyyy hh24:mi')) * 24  
                    WHEN TRUNC(DATE_LOGGED, 'dd') = TRUNC(DATE_LOGGED  + LEVEL - 1, 'dd') And To_Char(DATE_LOGGED  + LEVEL - 1, 'd') = '7' And TRUNC(DATE_LOGGED, 'dd') <> TRUNC(Nvl(DATE_CLOSED, To_Date('01.22.2021', 'mm.dd.yyyy')), 'dd') THEN (SLA_SUN_END - To_Date(To_Char(SLA_SUN_END, 'mm.dd.yyyy') || ' ' || TIME_LOGGED, 'mm.dd.yyyy hh24:mi')) * 24  
                  --
                    WHEN TRUNC(DATE_LOGGED, 'dd') = TRUNC(Nvl(DATE_CLOSED, To_Date('01.22.2021', 'mm.dd.yyyy')), 'dd') THEN (DATE_CLOSED - DATE_LOGGED) * 24
              ELSE
                    CASE
                        WHEN To_Char(DATE_LOGGED  + LEVEL - 1, 'd') = '1' THEN (SLA_MON_END - SLA_MON_START) * 24  
                        WHEN To_Char(DATE_LOGGED  + LEVEL - 1, 'd') = '2' THEN (SLA_TUE_END - SLA_TUE_START) * 24  
                        WHEN To_Char(DATE_LOGGED  + LEVEL - 1, 'd') = '3' THEN (SLA_WED_END - SLA_WED_START) * 24  
                        WHEN To_Char(DATE_LOGGED  + LEVEL - 1, 'd') = '4' THEN (SLA_THR_END - SLA_THR_START) * 24  
                        WHEN To_Char(DATE_LOGGED  + LEVEL - 1, 'd') = '5' THEN (SLA_FRI_END - SLA_FRI_START) * 24  
                        WHEN To_Char(DATE_LOGGED  + LEVEL - 1, 'd') = '6' THEN (SLA_SAT_END - SLA_SAT_START) * 24  
                        WHEN To_Char(DATE_LOGGED  + LEVEL - 1, 'd') = '7' THEN (SLA_SUN_END - SLA_SUN_START) * 24  
                    END    
              END "EFF_SERVICE_HOURS",
              --
                DATE_CLOSED "DATE_CLOSED"
            FROM
                sample
        WHERE
            TRUNC(DATE_LOGGED, 'dd') <= TRUNC(Nvl(DATE_CLOSED, To_Date('01.22.2021 10:09', 'mm.dd.yyyy hh:mi')), 'dd')
            CONNECT BY
                DATE_LOGGED + LEVEL - 1 <= DATE_CLOSED
            ORDER BY 
                DEPARTMENT, DATE_LOGGED + LEVEL - 1
        )       
    
SELECT              -- Get total service time as hh24:mi
    INCIDENT_REF "INCIDENT_REF",
    DEPARTMENT "DEPARTMENT",
    To_Char(DATE_LOGGED, 'MON-dd-yyyy hh24:mi') "DATE_LOGGED",
    To_Char(DATE_CLOSED, 'MON-dd-yyyy hh24:mi') "DATE_CLOSED",
    LPAD(FLOOR(Sum(EFF_SERVICE_HOURS * 60) / 60), 2, '0') || ':' || LPAD(Round((Sum(EFF_SERVICE_HOURS) - FLOOR(Sum(EFF_SERVICE_HOURS * 60) / 60)) * 60, 0), 2, '0') "TOTAL_SERVICE_TIME"
FROM
    days
GROUP BY 
    INCIDENT_REF,
    DEPARTMENT,
    DATE_LOGGED,
    DATE_CLOSED
ORDER BY 
    DEPARTMENT,
  INCIDENT_REF

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM