如何编写MySQL查询:统计客户的电视与收音机总购买量
嘿,既然你已经拿到了正确的统计结果,那咱们来聊聊怎么确认这个查询的合理性,以及有没有更高效简洁的写法吧~
确认与优化客户购买量统计查询
首先,先给你一个经过验证的靠谱写法,既能保证结果准确,也能避免常见的统计陷阱:
SELECT c.customerID, COALESCE(t.TotalTVsBought, 0) AS TotalTVsBought, COALESCE(r.TotalRadiosBought, 0) AS TotalRadiosBought FROM Customer c LEFT JOIN ( -- 先统计每个客户的总电视购买量 SELECT customerID, SUM(numTVsBought) AS TotalTVsBought FROM TV GROUP BY customerID ) t ON c.customerID = t.customerID LEFT JOIN ( -- 再统计每个客户的总收音机购买量 SELECT customerID, SUM(numRadiosBought) AS TotalRadiosBought FROM Radio GROUP BY customerID ) r ON c.customerID = r.customerID;
为什么这个写法值得信赖?
- 用
LEFT JOIN确保所有客户都会出现在结果中,哪怕某个客户从未买过电视或收音机 COALESCE把空值转换成0,让统计结果更直观,不会出现尴尬的NULL- 最关键的是:先聚合再关联,避免了直接关联TV和Radio明细表时产生的笛卡尔积问题——如果某个客户在TV表有3条记录、Radio表有2条记录,直接关联会生成6条临时记录,导致SUM的数值被错误放大。
如果你之前用了这种写法,要注意踩坑!
-- 不推荐的写法,存在统计错误风险 SELECT c.customerID, SUM(t.numTVsBought) AS TotalTVsBought, SUM(r.numRadiosBought) AS TotalRadiosBought FROM Customer c LEFT JOIN TV t ON c.customerID = t.customerID LEFT JOIN Radio r ON c.customerID = r.customerID GROUP BY c.customerID;
除非每个客户在TV和Radio表中都只有1条记录,否则这个查询的统计结果一定会出错——因为关联后的临时表会产生重复行,导致SUM计算时把同一笔购买多次累加。
另一种更紧凑的优化写法
如果你的数据库支持,也可以用UNION ALL合并两个表的记录后再统计,代码更简洁,大数据量下性能也不错:
SELECT c.customerID, SUM(CASE WHEN type = 'TV' THEN num ELSE 0 END) AS TotalTVsBought, SUM(CASE WHEN type = 'Radio' THEN num ELSE 0 END) AS TotalRadiosBought FROM Customer c RIGHT JOIN ( -- 把TV和Radio的购买记录统一格式后合并 SELECT customerID, numTVsBought AS num, 'TV' AS type FROM TV UNION ALL SELECT customerID, numRadiosBought AS num, 'Radio' AS type FROM Radio ) combined ON c.customerID = combined.customerID GROUP BY c.customerID;
你可以对比下自己之前的查询,如果和上面第一种或第三种写法一致,那结果肯定是准确的;如果是第二种写法,那得赶紧换成前面的靠谱版本哦~
内容的提问来源于stack exchange,提问作者MSJ
相关产品推荐
相关产品推荐

