如何用SQL查询由起止日期计算的到期日在未来5个工作日内的记录
解决SQL查询未来5个工作日到期记录的问题
你的原查询仅简单计算了日期间隔,未排除周末,无法准确筛选出未来5个工作日内到期的记录。下面针对不同主流数据库给出可行方案:
PostgreSQL
方案1:生成日期序列统计工作日
通过生成当前日期到到期日的所有日期,过滤周末后统计有效工作日数量:
SELECT * FROM your_table WHERE end_date >= CURRENT_DATE AND ( SELECT COUNT(*) FROM generate_series(CURRENT_DATE, end_date, INTERVAL '1 day') AS date_series WHERE EXTRACT(DOW FROM date_series) NOT IN (0, 6) -- 0=周日,6=周六 ) <= 5;
方案2:公式计算工作日差
通过日期差减去周末天数,效率更高:
SELECT * FROM your_table WHERE end_date >= CURRENT_DATE AND ( (end_date - CURRENT_DATE)::INTEGER - (EXTRACT(WEEK FROM end_date) - EXTRACT(WEEK FROM CURRENT_DATE))::INTEGER * 2 - CASE WHEN EXTRACT(DOW FROM CURRENT_DATE) = 0 THEN 1 ELSE 0 END - CASE WHEN EXTRACT(DOW FROM end_date) = 6 THEN 1 ELSE 0 END ) <= 5;
MySQL
方案1:使用内置WORKDAY函数
若你的MySQL版本支持WORKDAY()函数,可直接用它计算工作日差:
SELECT * FROM your_table WHERE end_date >= CURDATE() AND WORKDAY(CURDATE(), end_date) <= 5;
方案2:自定义工作日计算
无内置函数时,通过日期差减去周末天数实现:
SELECT * FROM your_table WHERE end_date >= CURDATE() AND ( DATEDIFF(end_date, CURDATE()) - FLOOR(DATEDIFF(end_date, CURDATE()) / 7) * 2 - CASE WHEN DAYOFWEEK(CURDATE()) = 1 THEN 1 ELSE 0 END -- DAYOFWEEK中1=周日 CASE WHEN DAYOFWEEK(end_date) = 7 THEN 1 ELSE 0 END -- 7=周六 ) <= 5;
SQL Server
方案1:使用DATEADD(WORKDAY)
SQL Server 2016及以上版本支持直接计算未来N个工作日的日期:
SELECT * FROM your_table WHERE end_date >= CAST(GETDATE() AS DATE) AND end_date <= DATEADD(WORKDAY, 5, CAST(GETDATE() AS DATE));
方案2:自定义工作日计算
针对旧版本,通过日期差减去周末天数实现:
SELECT * FROM your_table WHERE end_date >= CAST(GETDATE() AS DATE) AND ( DATEDIFF(day, CAST(GETDATE() AS DATE), end_date) - (DATEDIFF(week, CAST(GETDATE() AS DATE), end_date) * 2) - CASE WHEN DATEPART(dw, CAST(GETDATE() AS DATE)) = 1 THEN 1 ELSE 0 END -- dw=1是周日 CASE WHEN DATEPART(dw, end_date) = 7 THEN 1 ELSE 0 END -- dw=7是周六 ) <= 5;
注意:以上方案仅排除周末,若需同时排除节假日,需维护一个节假日表,在查询中额外过滤这些日期。
内容的提问来源于stack exchange,提问作者learner
相关产品推荐
相关产品推荐

