题目如下:

create table candidate(
	id int(11),
	name varchar(50)
);

create table vote(
	id int(11),
	candidate_id int(11)
);

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

输入: 
Candidate table:
+----+------+
| id | name |
+----+------+
| 1  | A    |
| 2  | B    |
| 3  | C    |
| 4  | D    |
| 5  | E    |
+----+------+
Vote table:
+----+-------------+
| id | candidate_Id |
+----+-------------+
| 1  | 2           |
| 2  | 4           |
| 3  | 3           |
| 4  | 2           |
| 5  | 5           |
+----+-------------+
输出: 
+------+
| name |
+------+
| B    |
+------+
解释: 
候选人B有2票。候选人C、D、E各有1票。
获胜者是候选人B。

最初的思路如下

1: 分组统计每个候选人的投票数 select candidate_id, count(id) as cnt from vote group by candidate_id ;

2: 计算最大的投票数的候选人ID

  • 错误示范
select 
	max(cnt)
from (
	select 
		candidate_id, count(id) as cnt
	from vote 
	group by candidate_id
) group by candidate_id
  • 示范2
select 
	max(cnt)
from (
	select 
		candidate_id, count(id) as cnt
	from vote 
	group by candidate_id
) group by candidate_id
  • 示范3 --
select 
    c.name
from candidate c 
inner join (
    select 
        max(cnt) as mt, candidateId
    from (
        select 
            candidateId ,count(id) as cnt
        from vote
        group by  candidateId 
    ) M
)F on c.id = F.candidateId

3: 关联候选人表查询结果

最终正确答案如下:

select 
    c.name
from candidate c 
inner join (
    select 
        candidateId, count(id) as cnt
    from Vote 
    group by candidateId 
    #  获取分组的最大值
    order by count(id) desc
    limit 1
) M on c.id = M.candidateId 

参考题解2(听说效率会提高)

select name
from candidate where id = (
	select 
  		candidateId
	from vote 
  	group by candidateId
  	order by count(*) desc
	limit 1
)

参考题解3(窗口函数 + 排序)


select 
	name
from (
	select 
		a.name
  		-- 以 group by分组后 在窗口函数以 count(b.id) 进行降序排列 
		-- 相当于实现了 候选人 的排名
		, dense_rank() over(order by count(b.id) desc) as rnk
	from candidate a
	join vote b
	on a.id = b.candidateid
	group by b.candidateId
) t where t.rnk = 1;


## 这个SQL相当于 实现了每个候选人的排名, 然后我们获取第一个即可.
	select 
		a.name
		, dense_rank() over(order by count(b.id) desc) as rnk
	from candidate a
	join vote b
	on a.id = b.candidateid
	group by b.candidateId

在leetcode执行结果如下:
{"headers": ["name", "rnk"], "values": [["B", 1], ["D", 2], ["C", 2], ["E", 2]]}
可以知道排名结果如下:
B 1
D 2
C 2
E 2

问题总结

其实获取分组排序的最大值可以通过 **排序 + limit** 即可轻松获取;

可是我开始的 时候没有想到, 通过再分组获取max.