题目来源:牛客网
首先制构造基础内容:
select
emp_no,
salary,
t_rank
from salaries
order by salary desc
其中t_rank尚未定义。现在再来看内容:对工资进行排序,相同的情况下根据序号排序。
这里难点有两个:第一点是emp_no方面的组合排序。第二点是t_rank上选出不跳数的排序。
方法1:使用自连结,在select *from salaries的情况下再次join salaries。这样可以将两个salaries都进行排序,然后一起输出。
初步思路如下
select
a.emp_no,
a.salary,
count(distinct b.salary) as t_rank
from salaries as a join salaries as b
on a.salary <= b.salary
group by a.emp_no, a.salary
order by a.salary desc, a.emp_no asc
使用两个相同的salary,以on a.salary <= b.salary为条件筛选后,b中的数字将会被t_rank按照“不小于a的salary数量”被使用,并用distinct避免跳过重合的数字
这个方法还有第二个表达方式:
select
a.emp_no,
a.salary,
count(distinct b.salary) as t_rank
from salaries a, salaries b
where a.salary <= b.salary
group by a.emp_no, a.salary
order by a.salary desc, a.emp_no asc
方法2:使用窗口函数dense_rank()
rank函数用于根据指定的ORDER BY子句给结果集中的每一行分配排名值,对于相同的数值会分配相同的排名,可以搭配order by 或者over()使用。这里使用后者的方法。
select
emp_no,
salary,
dense_rank() over(order by salary desc)
from salaries
这里dense_rank为不跳过的方法,若使用跳过的方法则应该换成rank()