[英]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.