文章目录
- [1 题目描述](#1 题目描述)
- [2 测试用例](#2 测试用例)
- [3 解题思路](#3 解题思路)
-
- [3.1 解法 1](#3.1 解法 1)
- [3.2 解法 2](#3.2 解法 2)
1 题目描述
表: Candidate
+-------------+----------+
| Column Name | Type |
+-------------+----------+
| id | int |
| name | varchar |
+-------------+----------+
id 是该表中具有唯一值的列
该表的每一行都包含关于候选对象的 id 和名称的信息.
表: Vote
+-------------+------+
| Column Name | Type |
+-------------+------+
| id | int |
| candidateId | int |
+-------------+------+
id 是自动递增的主键 (具有唯一值的列).
candidateId 是 id 来自 Candidate 表的外键 (reference 列).
该表的每一行决定了在选举中获得第 i 张选票的候选人.
编写解决方案来报告获胜候选人的名字 (即获得最多选票的候选人).
生成的测试用例保证 只有一个候选人赢得 选举
2 测试用例
输入:
Candidate table:
sql
+----+------+
| id | name |
+----+------+
| 1 | A |
| 2 | B |
| 3 | C |
| 4 | D |
| 5 | E |
+----+------+
Vote table:
sql
+----+-------------+
| id | candidateId |
+----+-------------+
| 1 | 2 |
| 2 | 4 |
| 3 | 3 |
| 4 | 2 |
| 5 | 5 |
+----+-------------+
输出:
sql
+------+
| name |
+------+
| B |
+------+
解释:
候选人 B 有 2 票. 候选人 C, D, E 各有 1 票
获胜者是候选人 B
3 解题思路
3.1 解法 1
- 使用
group by candidateId
对candidateId
分组统计被投票总数, 并按被投票次数, 倒序排序
sql
select candidateId, count(candidateId) as cnt
from Vote
group by candidateId
order by cnt desc
查询结果
candidateId | cnt |
---|---|
2 | 2 |
3 | 1 |
4 | 1 |
5 | 1 |
- 使用
limit 1
查找出票数最高的
sql
select candidateId, count(candidateId) as cnt
from Vote
group by candidateId
order by cnt desc
limit 1
查询结果
candidateId | cnt |
---|---|
2 | 2 |
- 通过票数最高的
candidateId
在Candidate
中查询name
sql
select c.name
from Candidate as c
inner join (select candidateId, count(candidateId) as cnt
from Vote
group by candidateId
order by cnt desc
limit 1) as v on c.id = v.candidateId;
查询结果
name |
---|
B |
上面的 sql 在最终结果没有使用 count(candidateId) as cnt
, 可以不需要这个, 简化 sql 复杂度
sql
select name
from Candidate
where id = (select candidateId
from Vote
group by candidateId
order by count(candidateId) desc
limit 1);
可以在 order by count(candidateId) desc
中直接使用统计函数 count
3.2 解法 2
- 使用
count(candidateId) over(partition by candidateId) as counts
分组统计candidateId
的投票数量, 需要使用distinct candidateId
对结果去重
sql
select distinct candidateId,
count(candidateId) over (partition by candidateId) as counts
from Vote
查询结果
candidateId | counts |
---|---|
2 | 2 |
3 | 1 |
4 | 1 |
5 | 1 |
- 对投票数量进行倒序排序, 使用
limit 1
查找出票数最高的
sql
select distinct candidateId,
count(candidateId) over (partition by candidateId) as counts
from Vote
order by counts desc
limit 1
查询结果
candidateId | counts |
---|---|
2 | 2 |
- 通过票数最高的
candidateId
在Candidate
中查询name
, 可以参照解法 1 中简化 sql, 将count(candidateId) over (partition by candidateId)
放在order by
中
sql
select name
from Candidate
where id = (select distinct candidateId
from Vote
order by count(candidateId) over (partition by candidateId) desc
limit 1);
查询结果
name |
---|
B |