高校选举MySQL查询:如何获取部门Member职位前6名候选人?
获取Informatique部门Member职位获胜者(支持平局处理)
首先给你提个小细节:你之前写的CHEF职位查询里有个笔误——GROUP BY candidates_votes.candidate_id应该是GROUP BY candidate_votes.candidate_id,而且用现代JOIN语法会比逗号分隔的关联方式更清晰,后面我也会给你优化后的版本。
回到你的核心需求:要获取Informatique部门Member职位的前6名,且支持票数平局的情况(也就是如果第6名有多个候选人票数相同,这些候选人都要被纳入结果),用MySQL的窗口函数DENSE_RANK()是最适合的方案,它能完美处理排名平局的场景。
最终查询语句
SELECT d.firstname, d.lastname, v.votes FROM ( SELECT cv.candidate_id, COUNT(*) AS votes, DENSE_RANK() OVER (ORDER BY COUNT(*) DESC) AS vote_rank FROM candidate_votes cv WHERE cv.candidate_position = 2 GROUP BY cv.candidate_id ) v JOIN department_candidates dc ON v.candidate_id = dc.doctor_id AND dc.candidate_position = 2 JOIN department dept ON dc.department_id = dept.id AND dept.name = 'Informatique' JOIN doctor d ON dc.doctor_id = d.id WHERE v.vote_rank <= 6 ORDER BY v.votes DESC, d.lastname ASC;
关键逻辑说明
DENSE_RANK()窗口函数:这个函数的特点是,相同票数的候选人会获得相同的排名,且排名不会出现跳跃(比如3个候选人同得第5名,下一个排名是6而不是8),这样就能保证所有进入前6排名梯队的候选人都被选中,哪怕最终结果数量超过6个。- 子查询统计票数与排名:先单独统计每个Member候选人的总票数,同时计算他们的排名,这样后续过滤和关联更高效。
- 部门过滤:通过
department_candidates和department表精准筛选出Informatique部门的参选者,避免跨部门统计。 - 排序规则:结果按得票数降序排列,票数相同的按姓氏升序排列,让结果更规整易读。
优化后的CHEF职位查询(可选)
如果你想优化原来的CHEF查询,让它更清晰且避免语法问题,可以用这个版本:
SELECT d.firstname, d.lastname, v.votes FROM ( SELECT cv.candidate_id, COUNT(*) AS votes FROM candidate_votes cv WHERE cv.candidate_position = 1 GROUP BY cv.candidate_id ) v JOIN department_candidates dc ON v.candidate_id = dc.doctor_id AND dc.candidate_position = 1 JOIN department dept ON dc.department_id = dept.id AND dept.name = 'Informatique' JOIN doctor d ON dc.doctor_id = d.id ORDER BY v.votes DESC;
这个版本用了标准JOIN语法,修正了笔误,同样支持平局场景——所有获得最高票数的CHEF候选人都会被列出。
内容的提问来源于stack exchange,提问作者Mohammad
相关产品推荐
相关产品推荐

