如何通过GROUP BY去重后获取单值统计总和?
解决SQL去重后返回单个统计总和的问题
嘿,这个问题其实很好搞定!你已经摸到了关键的突破口——用GROUP BY order_id消除重复订单数据的影响,现在只需要在这个分组查询的基础上,再做一次整体求和,就能得到和第一个查询格式完全一致的单个统计值了。
核心思路
先通过子查询(或者CTE)对每个唯一的order_id计算它的op_total总和,确保每个订单只被统计一次;然后在外层查询中对这些单个订单的总和做累加,最终返回一个单独的统计值。
具体实现方案
方案1:使用子查询(兼容性最强)
这种写法几乎支持所有SQL数据库,不用担心版本兼容问题:
SELECT CAST(SUM(order_total) AS INT) AS total FROM ( -- 先按order_id分组,计算每个订单的唯一总和 SELECT CAST(SUM(`op_total`) AS INT) AS order_total FROM `dashboard_sales` WHERE `op_status` IN ('settlement', 'capture') AND `order_date` BETWEEN '2018-01-01' AND '2019-06-30' AND `order_status` IN ('Ordered', 'Validated','Awaiting Packing','Packing Process','Ready to Ship','Shipped','Completed') GROUP BY `order_id` ) AS unique_orders;
方案2:使用CTE(公共表表达式,可读性更好)
如果你的数据库支持CTE(比如MySQL 8.0+、PostgreSQL、SQL Server等),这种写法逻辑更清晰:
WITH unique_orders AS ( -- 定义CTE,存储每个订单的唯一总和 SELECT CAST(SUM(`op_total`) AS INT) AS order_total FROM `dashboard_sales` WHERE `op_status` IN ('settlement', 'capture') AND `order_date` BETWEEN '2018-01-01' AND '2019-06-30' AND `order_status` IN ('Ordered', 'Validated','Awaiting Packing','Packing Process','Ready to Ship','Shipped','Completed') GROUP BY `order_id` ) -- 对CTE中的结果做整体求和 SELECT CAST(SUM(order_total) AS INT) AS total FROM unique_orders;
为什么这样有效?
- 内层的
GROUP BY order_id确保同一个order_id的所有重复记录只会被计算一次总和,彻底解决了重复数据导致统计结果偏大的问题。 - 外层的
SUM(order_total)把所有单个订单的总和累加起来,最终返回一个单独的数值,格式和你最初的查询完全一致。
内容的提问来源于stack exchange,提问作者Misdan
相关产品推荐
相关产品推荐

