题解 | #对所有员工的薪水按照salary降序进行1-N的排名#
对所有员工的薪水按照salary降序进行1-N的排名
http://www.nowcoder.com/practice/b9068bfe5df74276bd015b9729eec4bf
这题重点技巧如何计算出【1,2,2,3】这种不跳数字的排序
1.自联结:
select t1.emp_no, t1.salary, count( distinct t2.salary) as t_rank from salaries t1,salaries t2 where t1.salary <= t2.salary group by t1.emp_no,t1.salary order by t1.salary desc, t1.emp_no t1.salary <= t2.salary找出在查询t1.salary的时候有多少个t2.salary大于等于t1.salary。这里需要用distinct对t2.salary去重,不然出现的是【1,3,3,4】这种跳数字的排序。因为我们使用了聚合函数count()如果不加group by t1.emp_no的话,只会返回一条结果。同时goup by t1.salary也应该加上,因为salary属于列的字节名,不是主键且不唯一。而select子句只能存在常数、聚合函数、group by子句指定列(聚合键)。所以这里应该填上group by t1.salary。否则可能会出现记录不匹配的情况。
另一种写法(join):
select t1.emp_no, t1.salary, count(distinct t2.salary) as t_rank from salaries t1 join salaries t2 on t1.salary <= t2.salary group by t1.emp_no,t1.salary order by t1.salary desc, t1.emp_no
2.窗口函数:
select emp_no, salary, dense_rank() over(order by salary desc) as t_rank from salaries
DENSE_RANK()是一个窗口函数,它为分区或结果集中的每一行分配排名,而排名值没有间隙。
行的等级从行前的不同等级值的数量增加1。
引用看到其他小伙伴的贡献:
1、RANK()
在计算排序时,若存在相同位次,会跳过之后的位次。
例如,有3条排在第1位时,排序为:1,1,1,4······
2、DENSE_RANK()
这就是题目中所用到的函数,在计算排序时,若存在相同位次,不会跳过之后的位次。
例如,有3条排在第1位时,排序为:1,1,1,2······
3、ROW_NUMBER()
这个函数赋予唯一的连续位次。
例如,有3条排在第1位时,排序为:1,2,3,4······