棒球卡评分统计:GROUP BY如何显示无对应卡片评分的0计数?
解决棒球卡评分统计缺失0值行的问题
你现在的问题可以通过构造包含所有目标评分的基准数据集,再与原表左连接来解决,只需要一次查询就能得到所有评分的计数(包括0值),彻底解决循环查询的效率问题。
具体SQL实现(MySQL)
SELECT g.grade, COUNT(c.id) AS total FROM ( -- 构造所有需要统计的评分等级列表 SELECT 1 AS grade UNION ALL SELECT 1.5 UNION ALL SELECT 2 UNION ALL SELECT 2.5 UNION ALL SELECT 3 UNION ALL SELECT 3.5 UNION ALL SELECT 4 UNION ALL SELECT 4.5 UNION ALL SELECT 5 UNION ALL SELECT 5.5 UNION ALL SELECT 6 UNION ALL SELECT 6.5 UNION ALL SELECT 7 UNION ALL SELECT 7.5 UNION ALL SELECT 8 UNION ALL SELECT 8.5 UNION ALL SELECT 9 UNION ALL SELECT 10 ) AS g LEFT JOIN cards AS c ON c.grade = g.grade AND c.set = '1986' AND c.brand = 'fleer' AND c.cardnum = '57' GROUP BY g.grade ORDER BY g.grade;
关键说明
- 基准数据集:通过
UNION ALL生成你指定的所有评分等级,确保每个评分都能出现在结果中 - 左连接逻辑:使用
LEFT JOIN保留基准数据集中的所有评分,即使cards表中没有对应评分的记录 - 计数规则:用
COUNT(c.id)而非COUNT(*),因为左连接后无匹配的行中c.id为NULL,COUNT会自动忽略NULL值,得到0的计数 - 筛选条件位置:把原查询中的
set/brand/cardnum筛选放在ON子句中,而不是WHERE,避免过滤掉左连接后生成的0值行
其他数据库适配(可选)
如果使用PostgreSQL,可以用generate_series简化基准数据集的生成:
SELECT g.grade, COUNT(c.id) AS total FROM generate_series(1, 10, 0.5) AS g(grade) LEFT JOIN cards AS c ON c.grade = g.grade AND c.set = '1986' AND c.brand = 'fleer' AND c.cardnum = '57' GROUP BY g.grade ORDER BY g.grade;
内容的提问来源于stack exchange,提问作者Darryl
相关产品推荐
相关产品推荐

