为何SELECT id,COUNT(id)仅返回一行?候选ID计数查询结果不符
问题解答
1. 为何执行SELECT id, COUNT(id)仅返回一行?
COUNT()属于聚合函数,这类函数的作用是对整个结果集(或分组)做统计计算,返回单一结果值。当你的查询语句里同时包含非聚合列(比如id)和聚合函数,却没有指定GROUP BY子句时,数据库会把整张表的数据当作一个分组处理:
- 聚合函数
COUNT(id)会计算全表的总记录数,返回一个值; - 非聚合列
id的值是数据库从表中随机选取的一行数据(不同数据库的行为可能有差异,比如MySQL在关闭ONLY_FULL_GROUP_BY模式时会取第一行的id);
最终整个查询只会输出这一行结果。
2. 如何获取每个不同candidateId对应的表总记录数
给定Vote表数据:
| id | candidateId |
|---|---|
| 1 | 2 |
| 2 | 4 |
| 3 | 3 |
| 4 | 2 |
| 5 | 5 |
你的需求是得到每个不重复的candidateId一行,每行的统计值为表的总记录数(即5),可以用以下两种方案实现:
方案1:子查询+DISTINCT
SELECT DISTINCT candidateId, (SELECT COUNT(*) FROM Vote) AS total_count FROM Vote;
- 子查询
(SELECT COUNT(*) FROM Vote)单独计算出整张表的总记录数; DISTINCT关键字确保只返回不重复的candidateId;- 最终将每个不重复的
candidateId与总记录数关联输出。
方案2:交叉连接(CROSS JOIN)临时表
SELECT DISTINCT v.candidateId, t.total_count FROM Vote v CROSS JOIN (SELECT COUNT(*) AS total_count FROM Vote) t;
- 先通过子查询生成一个包含总记录数的临时表
t; - 用
CROSS JOIN将去重后的candidateId与临时表t做笛卡尔积,让每个candidateId都匹配到总记录数; DISTINCT同样用于过滤重复的candidateId行。
为什么之前的尝试不符合需求?
- 直接执行
SELECT DISTINCT candidateId, COUNT(candidateId):没有GROUP BY时,COUNT(candidateId)会统计全表数据,同时DISTINCT无法改变聚合函数的分组逻辑,最终只会返回一行随机的candidateId和全表计数; - 使用
GROUP BY candidateId:该语句会将相同candidateId的行分为一组,COUNT(candidateId)统计的是每组内的记录数(即每个候选人的得票数),而非全表总记录数,因此不符合你的需求。
内容的提问来源于stack exchange,提问作者brewandrew
相关产品推荐
相关产品推荐

