题目描述

(通过次数20,646 | 提交次数31,116,通过率66.35%)

表: Candidate
+-------------+----------+
| Column Name | Type     |
+-------------+----------+
| id          | int      |
| name        | varchar  |
+-------------+----------+
Id是该表的主键列。
该表的每一行都包含关于候选对象的id和名称的信息。

表:Vote
+-------------+------+
| Column Name | Type |
+-------------+------+
| id          | int  |
| candidateId | int  |
+-------------+------+
Id是自动递增的主键。
candidateId是id来自Candidate表的外键。
该表的每一行决定了在选举中获得第i张选票的候选人。

编写一个SQL查询来报告获胜候选人的名字(即获得最多选票的候选人)。
生成测试用例以确保 只有一个候选人赢得选举。

查询结果格式如下所示。
示例 1:
输入: 
Candidate table:
+----+------+
| id | name |
+----+------+
| 1  | A    |
| 2  | B    |
| 3  | C    |
| 4  | D    |
| 5  | E    |
+----+------+
Vote table:
+----+-------------+
| id | candidateId |
+----+-------------+
| 1  | 2           |
| 2  | 4           |
| 3  | 3           |
| 4  | 2           |
| 5  | 5           |
+----+-------------+
输出: 
+------+
| name |
+------+
| B    |
+------+
解释: 
候选人B有2票。候选人C、D、E各有1票。
获胜者是候选人B。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/winning-candidate
//测试数据
Create table If Not Exists Candidate (id int, name varchar(255));
Create table If Not Exists Vote (id int, candidateId int);

insert into Candidate (id, name) values ('1', 'A');
insert into Candidate (id, name) values ('2', 'B');
insert into Candidate (id, name) values ('3', 'C');
insert into Candidate (id, name) values ('4', 'D');
insert into Candidate (id, name) values ('5', 'E');

insert into Vote (id, candidateId) values ('1', '2');
insert into Vote (id, candidateId) values ('2', '4');
insert into Vote (id, candidateId) values ('3', '3');
insert into Vote (id, candidateId) values ('4', '2');
insert into Vote (id, candidateId) values ('5', '5');

解题思路

题目要求找出获胜候选人,实际上就是得票数最多的人。最终返回获胜候选人的姓名。

那么,我们可以通过以下几个步骤来实现:

**第一步**:根据Vote表中的投票记录,获取每个候选人的得票数;

Vote表中的每一行,就是一个投票记录。可以使用聚合函数分组统计得出。

当然,也可以使用开窗函数count得到。

**第二步**:根据第一步的结果,得出得票数最多的候选人的ID;

按第一步的得票数倒序排序,取出排名第一的候选人的ID。使用ORDER BY + LIMIT可以实现。

**第三步**:根据获胜候选人的ID,取出name;

直接关联Candidate表,或者使用IN子查询即可得出。

参考SQL

未特别说明的情况下,参考SQL为基于MySQL8.0实现。
select
    a.name
from Candidate a
inner join (
    select
        b.candidateId
    from Vote b
    group by b.candidateId
    order by count(1) desc
    limit 1
)c
on a.id = c.candidateId;
picture loss