
本文详解如何正确使用 group by 统计每位候选人(candidate)在各职位(position)上的实际得票数,解决窗口函数不支持 count(distinct) 的兼容性问题,并提供可直接运行的标准 sql 示例与关键注意事项。
本文详解如何正确使用 group by 统计每位候选人(candidate)在各职位(position)上的实际得票数,解决窗口函数不支持 count(distinct) 的兼容性问题,并提供可直接运行的标准 sql 示例与关键注意事项。
在实际数据库开发中,常需对多维组合字段(如 candidate + position)进行频次统计。题中需求——“john 在 referendum 职位获得 4 票”——本质是按候选人和职位双重分组后计数,而非去重计数(COUNT(DISTINCT candidate) 在此处逻辑错误且不适用)。原查询误用窗口函数 COUNT(DISTINCT) OVER (...),而 MariaDB 10.2 及更早版本确实不支持该语法,必须改用标准聚合方式。
✅ 正确解法是使用 GROUP BY 对 (candidate, position) 进行分组,并用 COUNT(*) 统计每组记录数:
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 anna | premier | 1 sofia | premier | 3
⚠️ 注意事项:
-
不要用
COUNT(DISTINCT candidate):本例中candidate在每组内已唯一(因GROUP BY candidate),COUNT(*)即为该候选人在此职位的总票数;若误写COUNT(DISTINCT candidate),结果恒为 1,失去统计意义。 -
反引号(`)非必需但推荐:当列名含关键字(如
position是 MySQL 保留字)或特殊字符时,使用反引号可避免语法错误;现代 MySQL 默认启用ANSI_QUOTES模式时尤其建议。 -
排序增强可读性:添加
ORDER BY position, votes_received DESC可按职位归类并按票数降序排列,便于人工核对。 -
验证数据一致性:执行前建议先运行
SELECT COUNT(*) FROM votes;确认总行数(题中为 10 行),再核对分组后SUM(votes_received)是否等于 10,确保无遗漏或重复。
该方案兼容 MySQL 5.7+、MariaDB 10.0+、PostgreSQL 及 SQL Server,是跨平台统计场景的稳健实践。

















