编者按
【MySQL5.7 二级分类统计文章数量方案】在开发 CMS、资讯、博客类系统时,经常会遇到二级栏目分类统计需求:文章只挂载在二级分类下,一级分类作为父级栏目,需要自动汇总它所有二级子分类下的文章总数,二级栏目则只展示自身的文章数量。
表结构说明:
分类表 class:id栏目 ID、classname栏目名称、fid父级 ID,fid=0代表一级分类,fid>0代表二级分类
文章表 news:classid绑定二级分类 ID,status=1代表正常已发布文章
坑点说明
很多同学一开始直接用分类左连接文章表统计,就会出现一级分类统计数量永远为 0的问题。 原因很简单:文章没有绑定一级分类 id,全部挂在二级,直接关联统计只会统计当前栏目本身绑定的文章,一级栏目下没有文章,所以数量是 0。
最终 SQL 方案(UNION ALL 合并一级汇总 + 二级独立统计)
-- 一级(汇总子分类)
SELECT
p.id,
p.classname,
p.fid,
COUNT(n.id) AS total
FROM `class` p
LEFT JOIN `class` c ON c.fid = p.id
LEFT JOIN `news` n ON n.classid = c.id AND n.status = 1
WHERE p.fid = 0
GROUP BY p.id, p.classname, p.fid
UNION ALL
-- 二级(只统计自己)
SELECT
c.id,
c.classname,
c.fid,
COUNT(n.id) AS total
FROM `class` c
LEFT JOIN `news` n ON n.classid = c.id AND n.status = 1
WHERE c.fid > 0
GROUP BY c.id, c.classname, c.fid
ORDER BY fid, id;
如果只统计二级分类就可以这样:
SELECT
c.id,
c.classname,
COUNT(n.id) AS count
FROM `class` c
LEFT JOIN `news` n ON c.id = n.classid AND n.status = 1
GROUP BY c.id, c.classname
ORDER BY c.id ASC;
使用小提示
1.如果不需要文章状态过滤,直接删除 AND n.status = 1;
2.建议给 news.classid、class.fid 建立索引,提升联表查询速度;
3.查询拿到结果后,PHP 可以循环组装树形数组,前端渲染一级栏目 + 子栏目列表。