如何计算工单账龄并排除周末日期?
计算工单账龄并排除周末的正确方法
问题分析
你当前的代码只过滤掉了创建日期为周末的工单,但并没有从账龄计算中排除创建日期到当前日期之间的所有周末,这才是结果不准的核心原因。你的WHERE子句只是筛选了非周末创建的工单,而非真正计算两个日期之间的工作日天数。
解决方案
要准确算出不含周末的工单账龄,推荐两种实用方法:
方法一:通用SQL计算逻辑
先算两个日期的总天数,再减去这段时间内的周末总数:
SELECT ticket_id, date_created::date, CURRENT_DATE, -- 计算两个日期的总天数 (CURRENT_DATE - date_created::date) AS total_days, -- 计算期间的周末天数 ( FLOOR((CURRENT_DATE - date_created::date + EXTRACT(DOW FROM date_created::date)) / 7) * 2 + CASE WHEN EXTRACT(DOW FROM CURRENT_DATE::date) < EXTRACT(DOW FROM date_created::date) THEN 2 ELSE 0 END + CASE WHEN EXTRACT(DOW FROM date_created::date) = 0 THEN 1 ELSE 0 END + CASE WHEN EXTRACT(DOW FROM CURRENT_DATE::date) = 6 THEN 1 ELSE 0 END ) AS weekend_days, -- 工作日账龄 = 总天数 - 周末天数 (CURRENT_DATE - date_created::date) - ( FLOOR((CURRENT_DATE - date_created::date + EXTRACT(DOW FROM date_created::date)) / 7) * 2 + CASE WHEN EXTRACT(DOW FROM CURRENT_DATE::date) < EXTRACT(DOW FROM date_created::date) THEN 2 ELSE 0 END + CASE WHEN EXTRACT(DOW FROM date_created::date) = 0 THEN 1 ELSE 0 END + CASE WHEN EXTRACT(DOW FROM CURRENT_DATE::date) = 6 THEN 1 ELSE 0 END ) AS "Case Aging (Workdays)" FROM Tickets -- 如果需要排除创建日期为周末的工单,保留此WHERE子句;否则可删除 WHERE EXTRACT(DOW FROM date_created::date) NOT IN (0, 6);
方法二:PostgreSQL专属简化写法
如果用PostgreSQL,可以借助generate_series生成日期序列,直接统计工作日数量:
SELECT ticket_id, date_created::date, CURRENT_DATE, COUNT(*) AS "Case Aging (Workdays)" FROM Tickets JOIN generate_series(date_created::date, CURRENT_DATE, '1 day'::interval) AS d(day) ON EXTRACT(DOW FROM d.day) NOT IN (0, 6) GROUP BY ticket_id, date_created::date, CURRENT_DATE;
原代码问题说明
你的原代码里,WHERE子句仅仅是把创建日期在周末的工单过滤掉了,但账龄计算还是用了CURRENT_DATE - date_created::date,这个结果包含了两个日期之间所有的周末天数,自然会和实际工作日账龄有偏差。
内容的提问来源于stack exchange,提问作者Hleki Mthombeni
相关产品推荐
相关产品推荐

