用SQL找出前N名

2021-09-07 13:10:36 字數 2399 閱讀 5455

業務系統中常常會有排名的需求,考試和比賽中則更普遍了。excel 中也有個 rank 函式供排名之用,資料庫中更不例外了。

如果須要找出工資最高的前三個員工工資(及其員工號)。

只是。「前三名」的詳細含義須要準確的定義。不然查出來的可能不是想要的結果。

首先。由於表中記錄數可能就少於三,查出來的記錄可能等於三條也可能少於三條。其次,須要考慮並列名次的處理。

假設名次不能並列,則還須要考慮是否要依據工資之外的列來區分排名。比如:

名次 id 工資

-------------

1 80 1000

2 90 1000

3 13 900

取前三名,則「4 19 900」不會被輸出。

假設名次能夠並列,則還有兩種不同方式。 1)名次並列,可是興許的名次要空出來。比如:

名次 id 工資

-------------

1 80 1000

1 90 1000

3 13 900

2)興許的名次不空出來。

名次 id 工資

-------------

1 80 1000

1 90 1000

2 13 900

在 oracle 的演示樣例資料庫中。針對上述三種不同的情況能夠通過不同的函式來實現。為了體現反覆資料的影響,取了前5名。

用 row_number()。

sql> select * from (select salary, row_number() over (order by salary desc) as seq from hr.employees) where seq <= 5;

salary seq

---------- ----------

24000 1

17000 2

17000 3

14000 4

13500 5

用 rank()。
sql> select * from (select salary, rank() over (order by salary desc) as seq from hr.employees) where seq <= 5;

salary seq

---------- ----------

24000 1

17000 2

17000 2

14000 4

13500 5

用 dense_rank()。
sql> select * from (select salary, dense_rank() over (order by salary desc) as seq from hr.employees) where seq <= 5;

salary seq

---------- ----------

24000 1

17000 2

17000 2

14000 3

13500 4

13000 5

第一種須要的結果相對簡單一點,可是結果集有些特殊(工資同樣的人可能僅僅有一部分被選擇出來)。在不支援 rank() 的系統中。能夠通過 limit 等方式變通實現:

select employee_id, salary from hr.employee order by salary desc limit 5;
假設連 limit 也沒有,僅僅同意採用最主要的 sql 構造。則更麻煩和低效。

基本思路是等價轉換須要的查詢「查工資的前五名」。比如:「工資的第1名」等價於「工資大於他的人為0人」。「工資的前5名」等價於「工資大於他的人不超過4人」。

也能夠轉換為「找出全部工資大於等於工資排名第五的人」。不要忘了處理排名並列的情況。

sql> select employee_id, salary from hr.employees o where (select count(distinct employee_id) from hr.employees where salary > o.salary) < 5 order by 2 desc, 1 desc;

employee_id salary

----------- ----------

100 24000

102 17000

101 17000

145 14000

146 13500

找出陣列前N大的數

這個題也是個比較有名的面試題.當然有很多變種.題目意思基本是 從乙個資料量很大的陣列裡找前n大的元素.不允許排序.這個題有兩個比較好的思路 思路一 用快速排序的思想,是思想,不是要排序 思路二 用最大堆的思想.我暫時只實現了思路一,思路二我之後實現了會補上.思路一比較簡單了.我們先用快排的思想找出第...

SQL查詢每個分組的前N條記錄

if object id tempdb.dbo.t is not null drop table t create table t id varchar 3 gid int,author varchar 29 title varchar 39 date datetime insert into t ...

SQL查詢每個分組的前N條記錄

在寫乙個儲存過程中,遇到了乙個問題,自己寫的 sql總是執行效率太低,於是上網搜尋,學到了乙個新招,都怪自己平時不愛學習啊,不過這個語法真的很厲害。需求 取乙個表中每個 id的最新三條資料 按照更新時間倒序取 select from t as t where 3 select count from ...