
本文详解如何使用 group by 正确统计每位候选人在各职位上的有效票数,解决窗口函数不支持 count(distinct) 的兼容性问题,并提供可运行的 sql 示例与关键注意事项。
本文详解如何使用 group by 正确统计每位候选人在各职位上的有效票数,解决窗口函数不支持 count(distinct) 的兼容性问题,并提供可运行的 sql 示例与关键注意事项。
在实际数据分析中,我们常需统计“每位候选人(candidate)在特定职位(position)上获得多少票”——注意:此处的“票数”指该候选人-职位组合出现的次数(即行数),而非对候选人去重后的总数。原始数据中存在重复记录(如 john + referendum 出现 4 次),目标输出正是对每组 (candidate, position) 进行计数,而非跨组去重。
你最初尝试使用窗口函数 COUNT(DISTINCT candidate) OVER (...),但 MariaDB(尤其旧版本)确实不支持 COUNT(DISTINCT) 作为窗口函数,这是语法限制,无法绕过。正确且通用的解决方案是使用 GROUP BY 聚合,它兼容所有主流 SQL 引擎(MySQL、MariaDB、PostgreSQL、SQL Server 等)。
✅ 推荐写法(简洁、标准、高效):
SELECT candidate, position, COUNT(*) AS votes_received FROM votes GROUP BY candidate, position ORDER BY position, votes_received DESC;
执行结果将准确匹配你的预期:
john | referendum | 4 mark | referendum | 2 sofia | premier | 3 anna | premier | 1
? 关键说明:
-
COUNT(*)统计每个分组内的行数,天然处理重复记录(无需DISTINCT); -
GROUP BY candidate, position确保按“人+职位”双重维度聚合,避免交叉计数; - 建议添加
ORDER BY提升可读性(如先按职位分组,再按票数降序); - 若字段名含保留字或特殊字符,可用反引号(如
`candidate`)包裹,但本例中非必需。
⚠️ 常见误区提醒:
- ❌ 错误:
SELECT DISTINCT candidate, position, COUNT(*) ...——DISTINCT与聚合函数混用会导致语法错误; - ❌ 错误:仅
GROUP BY candidate—— 将合并不同职位的票数(如 john 的 referendum 和 premier 票数相加); - ✅ 正确逻辑:*每个唯一
(candidate, position)对应一个分组,`COUNT()` 即该组合的出现频次**。
最后,若后续需进一步格式化为自然语言(如 "john, for the referendum, has 4 votes"),可在应用层拼接,或使用数据库字符串函数(如 MySQL 的 CONCAT):
SELECT CONCAT(candidate, ', for the ', position, ', has ', COUNT(*), ' votes') AS summary FROM votes GROUP BY candidate, position;
掌握 GROUP BY + COUNT(*) 是 SQL 聚合查询的基石,比依赖高级窗口函数更可靠、更易维护。

















