You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL关联两表汇总年度销售数据时聚合结果偏高问题

原SQL存在的问题
  • 连接类型选择错误:你用的JOIN默认是内连接(INNER JOIN),只会返回在两张表中都匹配到的员工,2021年新入职、2020年没有销售记录的员工会被直接过滤,无法出现在结果里。
  • 明细行直接关联产生笛卡尔积,这是销售额数值虚高的核心原因:如果某个员工2020年有3条销售记录,2021年有2条销售记录,按员工字段关联后会生成3*2=6条匹配记录,后续SUM计算时单条销售记录会被重复累加多次,结果必然远大于实际值。
  • 字段取值逻辑有漏洞:你直接取sales20表的staff和region字段,2021年新员工在sales20中无对应数据,这两个字段会返回空值,不符合展示要求。
修正方案

核心原则是先单独聚合每一年的销售数据算好累计值,再做表关联,从根源上避免明细行交叉匹配产生的重复计算问题。

适用于支持全外连接的数据库(PostgreSQL、Oracle、SQL Server等)

先分别聚合两张表得到年度维度的员工销售汇总,再对汇总结果做全外连接,用COALESCE函数补全员工、区域字段的空值:

SELECT 
  COALESCE(s20.staff, s21.staff) AS staff,
  COALESCE(s20.region, s21.region) AS region,
  s20.total_20,
  s21.total_21
FROM (
  SELECT staff, region, SUM(amount) AS total_20
  FROM sales20
  GROUP BY staff, region
) s20
FULL OUTER JOIN (
  SELECT staff, region, SUM(amount) AS total_21
  FROM sales21
  GROUP BY staff, region
) s21
ON s20.staff = s21.staff AND s20.region = s21.region

适用于不支持全外连接的数据库(如MySQL)

先通过UNION拿到两年所有出现过的员工+区域的全量去重名单,再分别左关联两年的聚合结果,兼容性更好:

WITH all_staff AS (
  SELECT staff, region FROM sales20
  UNION
  SELECT staff, region FROM sales21
),
sum20 AS (
  SELECT staff, region, SUM(amount) AS total_20 FROM sales20 GROUP BY staff, region
),
sum21 AS (
  SELECT staff, region, SUM(amount) AS total_21 FROM sales21 GROUP BY staff, region
)
SELECT 
  a.staff,
  a.region,
  sum20.total_20,
  sum21.total_21
FROM all_staff a
LEFT JOIN sum20 ON a.staff = sum20.staff AND a.region = sum20.region
LEFT JOIN sum21 ON a.staff = sum21.staff AND a.region = sum21.region

如果业务上不需要区分员工的所属区域变动,只需要按员工维度统计两年销售额,把上述所有SQL里的region字段从分组、关联条件中移除即可。

内容的提问来源于stack exchange,提问作者lyubomirsm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 10:51:31