PostgreSQL统计分类条目:如何为无数据分类返回0计数?
解决方案:返回指定分类的全量统计(含无数据分类)
嗨,这个需求我之前处理过,PostgreSQL 12.3里要实现你要的效果,关键是先构建包含所有目标分类ID的数据集,再和你的统计结果做左连接,这样就能把没有对应数据的分类也保留下来,并用0填充统计数。
直接用VALUES子句生成目标分类
如果只是临时指定分类ID,用VALUES子句生成一个临时的分类列表是最直接的方式,完整SQL如下:
SELECT COALESCE(stat.count, 0) AS count, target_cats.categoryId FROM -- 生成你需要的所有分类ID VALUES (1), (2), (3) AS target_cats(categoryId) LEFT JOIN ( -- 原来的统计查询作为子查询 SELECT COUNT(cee."entryId") AS count, cee."categoryId" FROM category_entries_entry cee WHERE cee."categoryId" IN (1, 2, 3) GROUP BY cee."categoryId" ) AS stat ON target_cats.categoryId = stat."categoryId" -- 按分类ID排序,和你期望的输出一致 ORDER BY target_cats.categoryId;
关键部分解释:
VALUES (1), (2), (3):手动创建一个包含所有目标分类ID的临时数据集,确保不管这些分类有没有数据,都会出现在结果里。LEFT JOIN:保留左边临时表的所有行,右边统计结果中没有匹配的分类,对应的count会是NULL。COALESCE(stat.count, 0):把NULL的统计数替换成0,完美符合你要的输出格式。
用分类表实现更灵活的查询
如果你有专门的categories分类表(推荐生产环境使用这种方式),可以直接从分类表中筛选目标ID,再左连接统计结果,这样后续修改分类ID更方便:
SELECT COALESCE(stat.count, 0) AS count, c.categoryId FROM categories c LEFT JOIN ( SELECT COUNT(cee."entryId") AS count, cee."categoryId" FROM category_entries_entry cee WHERE cee."categoryId" IN (1, 2, 3) GROUP BY cee."categoryId" ) AS stat ON c.categoryId = stat."categoryId" WHERE c.categoryId IN (1, 2, 3) ORDER BY c.categoryId;
这样执行后,就能得到你想要的输出:
| categoryId |
|---|
| 1 |
| 2 |
| 3 |
内容的提问来源于stack exchange,提问作者Albert
相关产品推荐
相关产品推荐

