SQL经典TopN问题解法

SQL解决TopN问题:从子查询到窗口函数
本文探讨了SQL中处理TopN问题的四种方法:关联子查询用于取最大值或最小值,窗口函数如ROW_NUMBER()、RANK()和DENSE_RANK()在分组上下文中寻找最高分,设置用户变量来获取特定排名,以及利用LIMIT语句直接筛选前N条记录。通过实例解析,帮助理解不同场景下的最优解法。

1、关联子查询

取最大值或最小值

SELECT * 
FROM score AS t1 
WHERE 成绩 = (SELECT max/min(成绩) 
			 FROM score AS t2 
			 WHERE t1.课程号 = t2.课程号);

取前两名

SELECT *
FROM score t1
WHERE (SELECT COUNT( * ) 
	   FROM score t2 
	   WHERE t1.课程号 = t2.课程号 AND t1.成绩 < t2.成绩 ) < 2
ORDER BY t1.课程号, t1.成绩 DESC; #排序便于观察

或者使用union all

# 使用union all
(SELECT * FROM score WHERE 课程号 = '0001' ORDER BY 成绩  DESC LIMIT 2)
UNION ALL
(SELECT * FROM score WHERE 课程号 = '0002' ORDER BY 成绩  DESC LIMIT 2)
UNION ALL
(SELECT * FROM score WHERE 课程号 = '0003' ORDER BY 成绩  DESC LIMIT 2);

2、窗口函数

根据需求选取ROW_NUMBER() OVER()、RANK() OVER()、DENSE_RANK() OVER()函数:

  • ROW_NUMBER() OVER():依次排序且不重复,不关注值
  • RANK() OVER():排序字段值相同的序号相同,且跳过相同的排名号,跳跃排序。例如[100,100,90],则对应的排名分别为1,1,3。
  • DENSE_RANK() OVER():排序字段值相同的序号相同,不跳过相同的排名号,连续排序。例如[100,100,90],则对应的排名分别为1,1,2。
#【TOPN万能模板】
SELECT * 
FROM (SELECT *, 
			 row_number() OVER (PARTITION BY 要分组的列名 ORDER BY 要排序的列名 DESC) AS ranking 
	  FROM 表名)  AS t  
WHERE ranking <= N;

查找每个学生成绩最高的两个科目

SELECT * 
FROM (SELECT *, 
			 row_number() OVER (PARTITION BY 学号 ORDER BY 成绩 DESC) AS ranking 
	  FROM score)  AS t1  
WHERE ranking <= 2;

3、设置用户变量来储存第N个数值

查找部门工资排前2的员工

SET @second=0;
SELECT DISTINCT AVG(salary)  INTO @second
FROM employees
GROUP BY department_id
ORDER BY AVG(salary) DESC
LIMIT 1 OFFSET 1;

SELECT department_id,AVG(salary)
FROM employees
GROUP BY department_id
HAVING AVG(salary)>=(SELECT @second)
ORDER BY AVG(salary) DESC

4、limit语句

查找工资排前N的员工(不分组)

# LeetCode 176-177题
Select ifnull(
          (SELECT DISTINCT Salary 
           from Employee 
           order by Salary desc 
           limit N-1,1) , null));
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值