我正在执行一项任务,其中有 2 个表。即tickets
和holidays
.
现在我也有了完成票证的天数。现在我需要通过排除假期(在 holidays
表中指定)和 weekends
来查找预期日期.
现在我可以使用 ticket created date
查找日期和days to complete the ticket
。但无法通过除去节假日和周末来计算预计预产期。
如果机票预计到期日恰逢节假日或周末,我们需要提前调整预计到期日。
之后我们需要比较ticket_closed_date
和expected_due_date
.
如果ticket_closed_date <= expected_due_date
然后需要返回isSlaMet
如YES
。否则需要返回isSlaMet
如NO
.
门票表
假期表
示例:通常,如果工单是在 2nd October,2020
创建的完成时间为 3
,那么预计到期日将为 5th October
我们有一个假期,5th October
。但工单创建日期和预计截止日期之间有 1 个假期和 2 个周末。即3rd, 4th and 5th of October
。因此我们需要将预计到期日延长 3 days
(因为 2 个周末 + 1 个假期)。即8th October
。门票截止日期:9th October
.
然后我们需要比较ticket closed date(9th october)
和expected due date(8th October)
并返回isSlaMet
如YES
.
预期输入
Tickets Table
--------------------------------------------------------------------------------
tid createdAt apply_sla ticket_closed_date days_to_complete
--------------------------------------------------------------------------------
100 2020-10-02 00:00:00 1 2020-10-09 00:00:00 3
--------------------------------------------------------------------------------
Holidays Table
----------------------------------------------
id holiday_date end_date
----------------------------------------------
20 2020-10-05 2020-10-05
----------------------------------------------
Along with the above holiday, we need to exclude Weekends.
预期输出
Tickets Table
--------------------------------------------------------------------------------------------------------------------------
tid createdAt apply_sla ticket_closed_date days_to_complete expected_due_date completedIn isSlaMet
--------------------------------------------------------------------------------------------------------------------------
100 2020-10-02 00:00:00 1 2020-10-09 00:00:00 3 2020-10-08 00:00:00 4 NO
--------------------------------------------------------------------------------------------------------------------------
这是我到目前为止一直在使用的查询。
SELECT
`t`.`tid`, `t`.`createdAt`, `t`.`days_to_complete`,
`t`.`ticket_closed_date`,`holidays`.`holiday_date`,
`holidays`.`end_date`, `t.apply_sla`,
IF(ISNULL(`t`.`ticket_closed_date`),
NULL,
IF((`t`.`apply_sla` = 1),
IF(((CAST(`t`.`createdAt` AS DATE) + INTERVAL (`t`.`days_to_complete` + 1) DAY) BETWEEN `holidays`.`holiday_date` AND `holidays`.`end_date`),
IF((CAST(`t`.`ticket_closed_date` AS DATE) <= (`holidays`.`end_date` + INTERVAL `t`.`days_to_complete` DAY)),
'YES',
'NO'),
IF((CAST(`t`.`ticket_closed_date` AS DATE) <= (`t`.`createdAt` + INTERVAL (`t`.`days_to_complete` + 1) DAY)),
'YES',
'NO')),
IF(((TO_DAYS(`t`.`ticket_closed_date`) - TO_DAYS(`t`.`createdAt`)) > (`t`.`days_to_complete` + 1)),
'NO',
'YES')
)
) AS `isSlaMet`
FROM
(`tickets` `t`
LEFT JOIN `holidays` ON (((CAST(`t`.`createdAt` AS DATE) + INTERVAL (`t`.`days_to_complete` + 1) DAY) BETWEEN `holidays`.`holiday_date` AND `holidays`.`end_date`)))
ORDER BY `t`.`tid` DESC;
最佳答案
这比看起来更复杂。最简单的方法可能是暴力破解:使用递归 CTE(仅在 MySQL 8.0 中可用)枚举票证创建日期和关闭日期之间的所有日期,然后过滤掉周末和节假日来计算 SLA 天数:
with recursive cte_tickets as (
select tid, created_at as dt, ticket_closed_date
from tickets
where apply_sla = 1
union all
select tid, dt + interval 1 day, ticket_closed_date
from cte_tickets
where dt < ticket_closed_date
)
select t.*,
t.created_at
+ interval (t.days_to_complete + sum(weekday(dt) in (5, 6) or h.holiday_date is not null)) day
as expected_due_date,
count(*) - sum(weekday(dt) in (5, 6) or h.holiday_date is not null) - 1 completed_in,
t.ticket_closed_date <= t.created_at
+ interval (t.days_to_complete + sum(weekday(dt) in (5, 6) or h.holiday_date is not null)) day
as is_sla_met
from tickets t
inner join cte_tickets ct on ct.tid = t.tid
left join holidays h on ct.dt between h.holiday_date and h.end_date
group by t.tid
<强> Demo on DB Fiddle :
tid | created_At | apply_sla | ticket_closed_date | days_to_complete | expected_due_date | completed_in | is_sla_met --: | :------------------ | :-------- | :------------------ | ---------------: | :------------------ | -----------: | ---------: 100 | 2020-10-02 00:00:00 | 1 | 2020-10-09 00:00:00 | 3 | 2020-10-08 00:00:00 | 4 | 0
关于mysql - 如何在 MySQL 中排除周末和节假日日期并查找预期日期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64230578/