SQL今日一題(19):表複用

這是SQL今日一題的第19篇文章ide

題目描述

對全部員工的當前(to_date='9999-01-01')薪水按照salary進行按照1-N的排名,相同salary並列且按照emp_no升序排列函數

用到的是salaries表
spa

圖片salaries表
題目給了輸出展現表以下,注意第2條和第3條記錄,薪資相同,排名都爲2。
圖片code

方法1

select s1.emp_no,s1.salary,count(distinct s2.salary) as rank
from salaries s1,salaries s2
where s1.salary <= s2.salary 
and s1.to_date = '9999-01-01' 
and s2.to_date = '9999-01-01'
group by s1.emp_no,s1.salary
order by s1.salary desc,s1.emp_no asc

一、這題的難點在於對1-N的排名的理解,在計算排序時,若存在相同位次,不會跳過以後的位次,好比有3條數據排名都是1,那麼排序爲1,1,1,2。orm

二、本題的思想在於對salaries表的複用。blog

三、先從salaries s1和salaries s2表中給定限定條件排序

  • and s1.to_date = '9999-01-01'  and s2.to_date = '9999-01-01'圖片

四、重點在於如何排名。where s1.salary <= s2.salary ,意思是有多少個s2.salary大於等於s1.salary,好比等於等於75508的有9469二、9000、8895八、88070、7550八、75508這6條數據,其中75508重複了2次,用count(distinct s2.salary)去重,獲得75508這個薪資的排名爲5。ci

五、用count了就用group by 分組一下it

  • group by s1.emp_no,s1.salary

六、最後按照s1.salary降序,相同s1.salary的按照emp_no升序排列

  • order by s1.salary desc,s1.emp_no asc

    圖片結果

方法2

select emp_no, salaries, 
dense_rank() over(order by salary descas rank
where to_date = '9999-01-01' 
order by salary desc, emp_no

一、用窗口函數來作排序,按照這題的要求,用dense_rank來寫,這個窗口函數求的排名會存在重複,意味着總數是減小的

二、dense_rank() over(order by salary desc),意思是按照salary降序排列,相同位次的不跳過以後的位次,就這一個窗口函數解決了表複用的問題,因此仍是要學會窗口函數。

知識點

dense_rank窗口函數

  • 窗口函數的格式:<窗口函數> over ( partition by 列1 order by列2 )

  • 對數據排序,當存在相同位次時,不跳過以後的位次

  • partition by 列1是按照列1進行分組

  • order by列2是按照列2進行排序

相關文章
相關標籤/搜索