MySQL子查询如何适配外层GROUP BY子句按销售经理分维度统计
问题原因与解决方案
核心问题
你当前使用的是无关联的独立子查询,没有绑定外层分组的销售经理维度,因此子查询始终统计全表符合条件的数据,无法和外层的分组维度对齐。即使你补充了日期过滤条件,也只会返回全表当日的汇总值,依然无法按销售经理拆分。
另外你的原SQL还存在语法问题:SUM(Profit * Amount) AS 'Total Profit'后缺少逗号,会直接触发语法报错。
推荐实现方案:条件聚合
不需要嵌套子查询,直接用CASE WHEN结合聚合函数即可,单次表扫描就能计算所有指标,性能远高于子查询写法,逻辑也更清晰:
SELECT Account_Manager AS name, SUM(Profit * Amount) AS `Total Profit`, -- 统计利润率低于50%的订单总利润 SUM(CASE WHEN Profit / Sell_at < 0.5 THEN Profit * Amount ELSE 0 END) AS `< 50%`, -- 统计利润率高于50%的订单总利润 SUM(CASE WHEN Profit / Sell_at > 0.5 THEN Profit * Amount ELSE 0 END) AS `> 50%` FROM sales WHERE Invoice_Date = 'some date' GROUP BY Account_Manager
注:这里简化了利润率计算逻辑,
Profit * Amount / (Sell_at * Amount)和Profit / Sell_at计算结果完全等价(Amount不为0的前提下),可以减少不必要的运算。
子查询写法的修正方案(不推荐)
如果一定要保留子查询的实现思路,需要将子查询和外层的销售经理、日期条件做关联:
SELECT s1.Account_Manager AS name, SUM(s1.Profit * s1.Amount) AS `Total Profit`, (SELECT sum(s2.Profit * s2.Amount) from sales s2 WHERE s2.Account_Manager = s1.Account_Manager AND s2.Invoice_Date = 'some date' AND s2.Profit / s2.Sell_at < 0.5) AS `< 50%`, (SELECT sum(s2.Profit * s2.Amount) from sales s2 WHERE s2.Account_Manager = s1.Account_Manager AND s2.Invoice_Date = 'some date' AND s2.Profit / s2.Sell_at > 0.5) AS `> 50%` FROM sales s1 WHERE s1.Invoice_Date = 'some date' GROUP BY s1.Account_Manager
该写法虽然能实现需求,但需要多次扫描表,数据量较大时性能远低于条件聚合方案。
内容的提问来源于stack exchange,提问作者Drum
相关产品推荐
相关产品推荐

