PostgreSQL如何修改现有查询实现仅统计工作日(排除周末)
PostgreSQL 排除周末的日期间隔计算方法
你原查询里的date_part('day', Min(date1) - date2)统计的是两个日期的自然日间隔,要排除周六周日只算工作日,不需要额外安装插件,用内置日期函数就能实现,下面给两种可直接替换的写法:
写法1:高性能数学计算版(适合大数据量场景)
直接替换你原查询里的days_to_open字段计算逻辑即可:
select [other columns], ( (Min(date1)::date - date2::date) - 2 * ((date_trunc('week', Min(date1)::date) - date_trunc('week', date2::date)) / 7) - CASE WHEN extract(dow from Min(date1)::date) < extract(dow from date2::date) THEN 2 ELSE 0 END - CASE WHEN extract(dow from date2::date) = 0 THEN 1 ELSE 0 END - CASE WHEN extract(dow from Min(date1)::date) = 6 THEN 1 ELSE 0 END ) AS days_to_open from X where [...] group by [...]
逻辑说明:
- 先计算两个日期的总自然日差
- 减去整周段内固定的周末天数(每周2天周末)
- 修正跨周、起止日期刚好落在周六/周日的边界误差,确保计数准确
- 先把字段显式转为
date类型,避免timestamp带的时分秒干扰间隔计算
写法2:直观易维护版(适合中小数据量场景)
如果不想记复杂的边界判断逻辑,可以用generate_series生成日期序列直接过滤统计,可读性更强:
select [other columns], ( SELECT count(*) FROM generate_series(date2::date, Min(date1)::date - interval '1 day', '1 day') AS calc_date WHERE extract(dow from calc_date) NOT IN (0, 6) -- 0代表周日,6代表周六,直接排除 ) AS days_to_open from X where [...] group by [...]
注意事项
- 以上写法默认
date2早于Min(date1),如果你的业务场景存在date2晚于date1的情况,可以在计算结果外套一层greatest(计算结果, 0)避免返回负数。 - 如果后续需要额外排除法定节假日,只需要在写法2的子查询里再加一层节假日表的关联过滤即可,扩展更方便。
内容的提问来源于stack exchange,提问作者JermaineJermaine
相关产品推荐
相关产品推荐

