CodeGym /課程 /SQL SELF /主要視窗函數: ROW_NUMBER()、 RANK()、...

主要視窗函數: ROW_NUMBER()、 RANK()、 DENSE_RANK()、 NTILE()

SQL SELF
等級 29, 課堂 1
開放

上一堂課我們已經搞懂為什麼要用視窗函數。現在來看一下具體有哪些函數,以及它們的結果。語法細節我們下堂課再說。

函數 ROW_NUMBER()

ROW_NUMBER() 這個函數會在一個 window 裡,給每一列一個獨一無二的編號。就是根據 ORDER BY 排序後,單純給每一列編號啦。

語法:

ROW_NUMBER() OVER ([PARTITION BY column] ORDER BY column)

說明:

  • PARTITION BY column(可選):把資料分成不同 group。如果沒寫,就是整個資料集一起編號。
  • ORDER BY column:決定要怎麼排序來編號。

範例:資料表列編號

來看一個 students 資料表,裡面有學生跟他們的分數。

SELECT * FROM students;
id name score
1 Eva Lang 95
2 Maria Chi 87
3 Alex Lin 78
4 Anna Song 95
5 Otto Mart 87

現在我們來根據分數(score)由高到低給每一列編號:

SELECT
    name, 
    score, 
    ROW_NUMBER() OVER (ORDER BY score DESC) AS row_num
FROM students;

結果:

name score row_num
Eva Lang 95 1
Anna Song 95 2
Maria Chi 87 3
Otto Mart 87 4
Alex Lin 78 5

每一列都拿到一個獨立的編號——而且是根據分數由高到低排序的。

這個操作很簡單但超實用——直接在查詢結果加上 row number。如果不用視窗函數,傳統 SELECT 是做不到的。

函數 RANK()

RANK() 跟 ROW_NUMBER() 很像,但它會考慮到一樣的值。如果有幾列分數一樣,它們會拿到一樣的 rank,下一個 rank 會跳號。

語法:

RANK() OVER ([PARTITION BY column] ORDER BY column)

範例:學生分數排名

我們用 RANK() 來看同一份資料:

SELECT
    name, 
    score, 
    RANK() OVER (ORDER BY score DESC) AS rank
FROM students;

結果:

name score rank
Eva Lang 95 1
Anna Song 95 1
Maria Chi 87 3
Otto Mart 87 3
Alex Lin 78 5

這裡分數一樣的列(95 跟 87)會拿到一樣的 rank,下一個 rank 會跳號。

函數 DENSE_RANK()

DENSE_RANK() 跟 RANK() 很像,但不會跳號。意思是如果有重複的值,下一個 rank 只會加一。

語法:

DENSE_RANK() OVER ([PARTITION BY column] ORDER BY column)

範例:密集排名

我們用 DENSE_RANK() 來看同一份資料:

SELECT
    name, 
    score, 
    DENSE_RANK() OVER (ORDER BY score DESC) AS dense_rank
FROM students;

結果:

name score dense_rank
Eva Lang 95 1
Anna Song 95 1
Maria Chi 87 2
Otto Mart 87 2
Alex Lin 78 3

這裡跟 RANK() 不一樣,rank 只會連續增加,不會跳號。

函數 NTILE()

NTILE() 這個函數會把資料分成 n 個一樣大的 group(分位數),然後給每一列一個 group 編號。

語法:

NTILE(n) OVER ([PARTITION BY column] ORDER BY column)
  • n:你想要分成幾個 group。

範例:把學生分成 3 組

我們把學生根據分數由高到低分成 3 組:

SELECT
    name, 
    score, 
    NTILE(3) OVER (ORDER BY score DESC) AS group_num
FROM students;

結果:

name score group_num
Eva Lang 95 1
Anna Song 95 1
Maria Chi 87 2
Otto Mart 87 2
Alex Lin 78 3

注意:如果資料沒辦法完全平均分組,多出來的列會先分到前面的 group。像這個例子,前兩組各有兩列,最後一組只有一列。

什麼時候該用哪個函數?

  • ROW_NUMBER():想要根據排序給每一列一個獨立編號時用。
  • RANK():要排名,遇到一樣的值會跳號。
  • DENSE_RANK():要排名,遇到一樣的值但不跳號。
  • NTILE():想要把資料平均分組時用。

這些函數都能讓你分析資料變得超彈性。只要你需要計算順序編號或分組,都可以用它們來搞定!

2
任務
SQL SELF, 等級 29, 課堂 1
上鎖
使用 `ROW_NUMBER` 進行行編號
使用 `ROW_NUMBER` 進行行編號
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION