LeetCode--574. 当选者

文章目录

  • [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

  1. 使用 group by candidateIdcandidateId 分组统计被投票总数, 并按被投票次数, 倒序排序
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
  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
  1. 通过票数最高的 candidateIdCandidate 中查询 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

  1. 使用 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
  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
  1. 通过票数最高的 candidateIdCandidate 中查询 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
相关推荐
0xDevNull1 天前
MySQL索引进阶用法
后端·mysql
0xDevNull1 天前
MySQL索引用法
mysql
程序员小崔日记2 天前
一篇文章彻底搞懂 MySQL 和 Redis:原理、区别、项目用法全解析(建议收藏)
redis·mysql·项目实战
武子康2 天前
大数据-241 离线数仓 - 实战:电商核心交易数据模型与 MySQL 源表设计(订单/商品/品类/店铺/支付)
大数据·后端·mysql
用户8307196840822 天前
MySQL 查询优化 30 条封神技巧:用好索引,少耗资源,查询快到飞起
mysql
Nyarlathotep01132 天前
事务隔离级别
sql·mysql
Nyarlathotep01133 天前
SQL的事务控制
sql·mysql
用户86178277365183 天前
MySQL 8.0从库宕机排查实录:中继日志膨胀引发的连锁故障复盘
mysql
随风飘的云4 天前
mysql的innodb引擎对可重复读做了那些优化,可以避免幻读
mysql
于眠牧北7 天前
MySQL的锁类型,表锁,行锁,MVCC中所使用的临键锁
mysql