如何在MySQL中统计一个月内每日两类状态的订单数量并分列展示
别担心,我来帮你搞定这个订单状态统计的问题!其实核心思路就是用条件聚合来实现同一行展示不同状态的统计数据,按日期分组就行,我一步步给你讲清楚:
核心逻辑说明
你需要的是把两种状态的统计结果放在同一行的不同列里,这时候用CASE WHEN配合聚合函数(比如SUM或COUNT)就能实现:
- 对每一行订单,判断它的状态是不是1,如果是就记为1,否则记为0,最后把这些值加起来,就是状态1的订单总数
- 同理处理状态2的情况,这样就能在同一行得到两个状态的统计数
完整SQL示例
假设你的订单表(Order)里存储日期的字段是order_date(如果不是,替换成你实际的字段名就行),下面是可以直接用的查询语句:
SELECT DATE(order.order_date) AS order_date, -- 提取纯日期部分,确保同一日期的订单归为一组 SUM(CASE WHEN order.status = 1 THEN 1 ELSE 0 END) AS status, SUM(CASE WHEN order.status = 2 THEN 1 ELSE 0 END) AS status_1 FROM `Order` AS order -- 因为Order是MySQL的保留关键字,所以用反引号包裹避免报错 GROUP BY DATE(order.order_date) -- 按日期分组,必须和SELECT里的非聚合字段一致 ORDER BY order_date; -- 按日期排序,让结果更直观
逐部分解释
DATE(order.order_date):如果你的日期字段包含时分秒(比如2024-05-20 14:30:00),用DATE()函数可以提取出纯日期部分,保证同一天的所有订单都被分到同一组里。如果你的日期字段本身就是纯日期(比如2024-05-20),直接写字段名就行。SUM(CASE ...):这个是关键!CASE WHEN会逐个判断订单的状态,符合条件就返回1,不符合返回0,SUM把这些值加起来,就是对应状态的订单总数。你也可以用COUNT来实现,效果一样:
因为COUNT(CASE WHEN order.status = 1 THEN 1 END) AS statusCOUNT会忽略NULL值,当状态不符合时CASE返回NULL,所以统计的就是符合条件的订单数。GROUP BY:必须和SELECT里的非聚合字段(也就是日期字段)保持一致,这样SQL才知道要按什么维度分组统计。- 反引号包裹
Order:Order是MySQL的保留关键字,直接用会报错,所以用反引号`把它包起来就没问题了。
额外说明
如果你的统计需要关联Outlet表(比如按门店+日期分组),只需要加上JOIN语句并调整GROUP BY即可,比如:
SELECT outlet.outlet_name, DATE(order.order_date) AS order_date, SUM(CASE WHEN order.status = 1 THEN 1 ELSE 0 END) AS status, SUM(CASE WHEN order.status = 2 THEN 1 ELSE 0 END) AS status_1 FROM `Order` AS order JOIN Outlet AS outlet ON order.outlet_id = outlet.id -- 替换成实际的关联字段 GROUP BY outlet.outlet_name, DATE(order.order_date) ORDER BY order_date;
这样就能得到你想要的按日期分组、分两列展示不同状态订单数的结果啦!
内容的提问来源于stack exchange,提问作者Rizky Prasetya
相关产品推荐
相关产品推荐

