窗口函数
简单理解就是rank()、dense_rank()用来获取排名,可以用partition by
来分组,order by
对某一字段的数据进行排名。
1、RANK()
在计算排序时,若存在相同位次,会跳过之后的位次。
例如,有3条排在第1位时,排序为:1,1,1,4······
2、DENSE_RANK()
这就是题目中所用到的函数,在计算排序时,若存在相同位次,不会跳过之后的位次。
例如,有3条排在第1位时,排序为:1,1,1,2······
语法:
<窗口函数> OVER ( ORDER BY <排序用列清单> )
举例
例1:[LC185]. 部门工资前三高的所有员工
思路:
此题要获得各部门的前三高工资的员工,在使用窗口函数时注意用partition by进行分组排序,而不是对整个表进行salary的降序排列。
select b.name department ,a.name Employee ,a.salary
from (select c.* ,
dense_rank() over( partition by departmentid order by salary desc ) as 'num'
from employee c ) a
left join department b
on a.departmentid=b.id
where b.name is not null and a.num<=3;
例2:查询各科成绩前三名的记录
思路:
先使用rank() over (partition by CId order by score)
获取每门课的学生排名,作为表a,与学生表s查询出每门课前三名学生信息。
select a.CId, s.*, a.score, a.rank
from Student s,
(select sc.*, rank() over (partition by sc.CId order by sc.score desc) as rank
from SC sc) as a
where s.SId = a.SId and a.rank <= 3
order by a.CId;
结果为
------------------------------------我是分割线-----------------------------------------
另附两道常出的sql题目
查出每门课都大于60的学生
SELECT s.* FROM Student s,
(SELECT sc.SId AS SId FROM SC sc
GROUP BY sc.SId
HAVING MIN(sc.score) > 60) a
WHERE s.`SId` = a.SId;