如何在查询中指定工作日/周末时间范围,统计非工作时段请求量?
嗨,作为编程新手遇到这种带分支条件的查询确实容易懵,我来一步步帮你理清楚怎么构建这个统计查询~
分步构建非工作时段请求统计查询
1. 先拆核心逻辑
我们要把筛选条件拆成两个核心部分:
- 时间范围:只统计过去30天内收到的请求
- 时段判断:区分工作日和周末,筛选出不在对应工作时段的请求
2. 用对日期时间判断工具
从你写的interval '30 day'来看,应该是用PostgreSQL,那我们就以它为例(后面会提其他数据库的调整方法):
- 用
extract(isodow from receivedat)获取星期几:1=周一,5=周五,6=周六,7=周日(这个编号规则很直观,不容易搞混) - 用
receivedat::time把datetime字段转换成纯时间,方便和设定的工作时段对比
3. 完整查询示例
假设你的工作日工作时段是9:00-18:00,周末是10:00-16:00,统计请求数量的SQL如下:
SELECT COUNT(*) AS non_work_hour_requests FROM your_table_name -- 记得替换成你的实际表名 WHERE -- 第一部分:筛选过去30天内的请求 receivedat >= NOW() - INTERVAL '30 day' AND -- 第二部分:非工作时段的判断逻辑 ( -- 工作日(周一到周五):时间不在9:00-18:00之间 ( EXTRACT(ISODOW FROM receivedat) BETWEEN 1 AND 5 AND NOT (receivedat::TIME BETWEEN '09:00:00' AND '18:00:00') ) OR -- 周末(周六到周日):时间不在10:00-16:00之间 ( EXTRACT(ISODOW FROM receivedat) IN (6, 7) AND NOT (receivedat::TIME BETWEEN '10:00:00' AND '16:00:00') ) );
4. 关键部分给你唠明白
NOW() - INTERVAL '30 day':获取当前时间往前推30天的时间点,确保只统计最近30天的数据(如果想按自然日算,也可以换成current_date - INTERVAL '30 day')EXTRACT(ISODOW FROM receivedat):这个函数的星期编号很靠谱,不会像有些数据库那样把周日当成1,避免判断出错NOT (...):因为我们要的是非工作时段,所以对“在工作时段内”的条件取反就行- 括号的作用:把工作日和周末的条件分别包裹,再用
OR连接,逻辑更清晰
5. 换数据库也能适配
如果用的不是PostgreSQL,只需要修改日期判断函数:
- MySQL:用
DAYOFWEEK(receivedat)(注意这里1=周日,2=周一,6=周五,7=周六),时间对比用TIME(receivedat) - SQL Server:用
DATEPART(WEEKDAY, receivedat)(默认周日是1,你可以用SET DATEFIRST 1改成周一为1),时间对比用CAST(receivedat AS TIME)
6. 按需调整工作时段
你完全可以根据实际情况修改'09:00:00'、'18:00:00'这些时间值,比如如果工作日是8:30-17:30,直接替换成对应的时间字符串就好。
内容的提问来源于stack exchange,提问作者Cody
相关产品推荐
相关产品推荐

