WEEKDAY()返回0–6,周一为0、周日为6;DAYOFWEEK()返回1–7,周日为1,二者不可混用。统计工作日订单需用WEEKDAY(order_time) BETWEEN 0 AND 4。

WEEKDAY函数返回值和星期映射关系必须搞清
MySQL的WEEKDAY()返回 0–6 的整数,但和日常认知的“周一=1、周日=7”不同:它固定以周一为 0,周日为 6。这个偏移量直接影响统计逻辑,一旦按习惯当成周日=0就会全错。
-
WEEKDAY('2024-06-10')(周一)→ 返回0 -
WEEKDAY('2024-06-15')(周六)→ 返回5 -
WEEKDAY('2024-06-16')(周日)→ 返回6
如果你用DAYOFWEEK(),结果是 1–7(周日=1),两者不能混用。实际写WHERE或CASE时,务必先确认你用的是哪个函数。
统计工作日订单量:WHERE + WEEKDAY组合写法
要查某月工作日(周一至周五)的订单总数,直接在WHERE里过滤WEEKDAY(order_time)范围即可:
SELECT COUNT(*) AS workday_count FROM orders WHERE order_time >= '2024-06-01' AND order_time < '2024-07-01' AND WEEKDAY(order_time) BETWEEN 0 AND 4;
注意:
-
BETWEEN 0 AND 4对应周一到周五,不是 1–5 - 时间范围推荐用左闭右开(
< '2024-07-01'),避免时分秒截断误差 - 如果
order_time字段没索引,WEEKDAY(order_time)会导致全表扫描;建议加函数索引(MySQL 8.0+):CREATE INDEX idx_weekday ON orders (WEEKDAY(order_time));
按工作日分组汇总:GROUP BY WEEKDAY要搭配CASE才可读
直接GROUP BY WEEKDAY(order_time)出来的分组是 0–4,但报表需要显示“周一”“周二”这类标签,得用CASE转换:
SELECT
CASE WEEKDAY(order_time)
WHEN 0 THEN '周一'
WHEN 1 THEN '周二'
WHEN 2 THEN '周三'
WHEN 3 THEN '周四'
WHEN 4 THEN '周五'
END AS weekday_name,
COUNT(*) AS cnt
FROM orders
WHERE WEEKDAY(order_time) BETWEEN 0 AND 4
GROUP BY WEEKDAY(order_time)
ORDER BY WEEKDAY(order_time);关键点:
- 必须在
GROUP BY和ORDER BY里都用WEEKDAY(order_time),不能只用CASE表达式,否则MySQL 5.7会报错 - 如果漏掉
WHERE过滤,周日/周六(5/6)也会进结果,但CASE没覆盖,变成NULL,容易误判数据完整性
跨时区或自定义工作日时,WEEKDAY不够用
WEEKDAY()完全依赖MySQL服务器的默认时区和语言设置,不支持传参调整起始日。如果你的业务定义“周五+周六为工作日”,或者要适配不同地区(如中东国家周六日休),它就无能为力。
- 别硬套
WEEKDAY()加偏移计算,比如(WEEKDAY(dt) + 2) % 7来把周日当0——逻辑易错且不可维护 - 更稳妥的方式是用
DAYOFWEEK()配合自定义映射表,或在应用层处理日期分类逻辑 - 涉及时区转换(如订单时间存UTC,需按用户本地工作日统计),先用
CONVERT_TZ()转时区,再算WEEKDAY(),顺序不能反
时区、自定义工作制、节假日剔除——这些一叠加,单靠WEEKDAY()已经撑不住了。真要严谨统计,得把日期逻辑从SQL里摘出来。


















