如何编写SQL查询按月份统计超市销售总额?
修正每月销售总额统计的SQL查询错误
你的查询报错核心原因有两个:一是SELECT子句中的MONTHNAME(STR_TO_DATE(...))未出现在GROUP BY子句中(严格SQL模式下,非聚合列必须属于分组依据);二是在GROUP BY查询中添加了多余的DISTINCT——GROUP BY本身就会按分组字段自动去重,不需要额外使用DISTINCT。
下面是两种修正后的可行写法:
写法一:直接调整分组与选择字段
SELECT MONTHNAME(STR_TO_DATE(`date`, '%m/%d/%Y')) AS 'Month', YEAR(STR_TO_DATE(`date`, '%m/%d/%Y')) AS 'Year', SUM(`total`) AS 'TotalSales' FROM `supermarket_sales` GROUP BY YEAR(STR_TO_DATE(`date`, '%m/%d/%Y')), MONTH(STR_TO_DATE(`date`, '%m/%d/%Y')) ORDER BY YEAR(STR_TO_DATE(`date`, '%m/%d/%Y')), MONTH(STR_TO_DATE(`date`, '%m/%d/%Y'))
或者利用别名简化(部分数据库支持在GROUP BY中使用SELECT里的别名):
SELECT MONTHNAME(STR_TO_DATE(`date`, '%m/%d/%Y')) AS 'Month', YEAR(STR_TO_DATE(`date`, '%m/%d/%Y')) AS 'Year', SUM(`total`) AS 'TotalSales' FROM `supermarket_sales` GROUP BY Year, MONTH(STR_TO_DATE(`date`, '%m/%d/%Y')) ORDER BY Year, MONTH(STR_TO_DATE(`date`, '%m/%d/%Y'))
写法二:先预处理日期(更简洁易读)
如果你的数据库支持CTE(比如MySQL 8.0+、PostgreSQL等),可以先统一转换日期格式,避免重复写转换函数:
WITH processed_sales AS ( SELECT STR_TO_DATE(`date`, '%m/%d/%Y') AS sale_date, `total` FROM `supermarket_sales` ) SELECT MONTHNAME(sale_date) AS 'Month', YEAR(sale_date) AS 'Year', SUM(total) AS 'TotalSales' FROM processed_sales GROUP BY Year, MONTH(sale_date) ORDER BY Year, MONTH(sale_date)
关键说明
- 移除了SELECT中的
DISTINCT,GROUP BY会自动按年、月分组,每个分组仅返回一行汇总结果。 - 确保分组依据的是年份数值和月份数值,这样即使不同年份的同月(比如2023年1月和2024年1月)也会被正确区分开,同时月份名称可以通过数值安全转换得到。
内容的提问来源于stack exchange,提问作者John Beasley
相关产品推荐
相关产品推荐

