如何将应用内存中的表映射为MySQL/MariaSQL查询语句?
搞定MySQL/MariaSQL分类库存统计的坑
我太懂这种谷歌搜遍都找不到精准解决方案的憋屈了!之前处理多关联表的统计需求时,也在类似的场景上栽过跟头,刚好借你说的产品/分类例子把问题掰碎了说清楚。
先看基础场景(一对多关联)
如果你的产品和分类是一个分类对应多个产品的简单关系(比如products表直接有category_id字段),那你说的INNER JOIN+SUM+GROUP BY确实能正常工作。假设表结构是:
products:id,name,stock_quantity,category_idcategories:id,name
对应的SQL写法是:
SELECT c.name AS category_name, SUM(p.stock_quantity) AS total_stock FROM categories c INNER JOIN products p ON c.id = p.category_id GROUP BY c.id, c.name;
重点解决你可能遇到的坑:多对多关联重复统计
我猜你大概率是遇到了一个产品属于多个分类的情况(比如需要中间表product_categories关联产品和分类),这时候直接用INNER JOIN会让单个产品被多次关联,导致SUM出来的库存总量被重复计算,结果完全不对。
比如表结构是:
products:id,name,stock_quantitycategories:id,nameproduct_categories:product_id,category_id
这时候要先确保每个产品的库存只被计算一次,正确的写法有两种:
方法1:先聚合产品再关联分类
通过子查询先取出产品的唯一库存记录,再和分类关联,避免重复:
SELECT c.name AS category_name, SUM(p.stock_quantity) AS total_stock FROM categories c INNER JOIN product_categories pc ON c.id = pc.category_id INNER JOIN ( SELECT id, stock_quantity FROM products ) p ON pc.product_id = p.id GROUP BY c.id, c.name;
方法2:用关联子查询计算分类库存
这种写法逻辑更直观,直接针对每个分类计算其关联产品的库存总和:
SELECT c.name AS category_name, COALESCE( (SELECT SUM(stock_quantity) FROM products p JOIN product_categories pc ON p.id = pc.product_id WHERE pc.category_id = c.id), 0 ) AS total_stock FROM categories c;
这里用COALESCE把没有产品的分类的库存总和设为0,避免出现NULL。
额外小技巧
- 如果你的
stock_quantity可能有NULL值,记得用SUM(COALESCE(p.stock_quantity, 0))把NULL转为0再求和,避免结果为NULL。 - 如果需要包含没有任何产品的分类,把INNER JOIN改成LEFT JOIN即可(配合上面的COALESCE处理空值)。
内容的提问来源于stack exchange,提问作者Florian Mertens
相关产品推荐
相关产品推荐

