如何统计Orders表中CreatedAt(datetime2)字段对应的各工作日订单总数?
统计一周七天的订单数量查询方案
嘿,这事儿好办!要实现全表范围内每个工作日的订单统计,而且必须覆盖一周七天(哪怕某天没订单也要显示0),我给你写个适配SQL Server的查询语句,顺便拆解下思路:
完整查询语句
WITH WeekDays AS ( SELECT 'Monday' AS DayName UNION ALL SELECT 'Tuesday' UNION ALL SELECT 'Wednesday' UNION ALL SELECT 'Thursday' UNION ALL SELECT 'Friday' UNION ALL SELECT 'Saturday' UNION ALL SELECT 'Sunday' ) SELECT w.DayName + ':' + CAST(COUNT(o.CreatedAt) AS VARCHAR(10)) AS OrderCountByDay FROM WeekDays w LEFT JOIN Orders o ON DATENAME(weekday, o.CreatedAt) = w.DayName GROUP BY w.DayName -- 按周一到周日的固定顺序排序,避免字母排序混乱 ORDER BY CASE w.DayName WHEN 'Monday' THEN 1 WHEN 'Tuesday' THEN 2 WHEN 'Wednesday' THEN 3 WHEN 'Thursday' THEN 4 WHEN 'Friday' THEN 5 WHEN 'Saturday' THEN 6 WHEN 'Sunday' THEN 7 END;
关键逻辑说明
- 生成完整星期列表:用CTE
WeekDays预先定义一周七天的名称,这一步是为了保证哪怕某天没有订单,结果里也会显示该天的统计(数值为0),不会漏掉任何一天; - 关联订单表:通过
LEFT JOIN和DATENAME(weekday, o.CreatedAt)函数,把每个订单的创建时间映射到对应的星期名称上,这个函数不受SQL Server的DATEFIRST设置影响,匹配更可靠; - 统计与格式化:
COUNT(o.CreatedAt)会自动忽略LEFT JOIN后无订单的NULL值,得到对应星期的订单数,再和星期名称拼接成你要的Monday:52这种格式; - 固定排序:用
CASE语句指定排序规则,确保结果按周一到周日的顺序输出,而不是默认的字母顺序。
如果你的数据库不是SQL Server,只需要替换对应的星期提取函数就行(比如MySQL用DAYNAME(),PostgreSQL用TO_CHAR(CreatedAt, 'Day')),核心逻辑是一样的。
内容的提问来源于stack exchange,提问作者Sknecht
相关产品推荐
相关产品推荐

