2018年1月25日 星期四

次序函數

ROW_NUMBERRANKDENSE_RANK函數將依指定資料值(欄位)為每筆資料產生從1N的整數值(integer)流水序號,N的值可能小於或等於記錄筆數,三者唯一區別在於同值(同名)排名策略。
函數
並列名次
排名連續
說明
ROW_NUMBER()
連續
對結果集的每一筆資料均賦予一個遞增的整數值
RANK()
不一定連續
每一筆資料均賦予一個遞增的整數值。
但資料值相同時,則賦予相同名次(跳號)
DENSE_RANK()
連續
RANK()類似。差別在於DENSE_RANK()排名不會略過資料值相同的名次(不跳號)

指令將依據資料排序定義產生次序編號,因此也稱為次序函數,排序為重要且必要之參考項目(ORDER BY子句)。語法如下:
ROW_NUMBER
ROW_NUMBER() OVER ([PARTITION BY ] <ORDER BY clause>)

RANK
RANK() OVER ([PARTITION BY ] <ORDER BY clause>)

DENSE_RANK
DENSE_RANK() OVER ([PARTITION BY ] <ORDER BY clause>)

範例SQL語法及結果如下:
SELECT No
     , Name
     , Score
     , ROW_NUMBER() OVER (ORDER BY Score DESC) "ROW_NUMBER"
     , RANK() OVER (ORDER BY Score DESC)        "RANK"
     , DENSE_RANK() OVER (ORDER BY Score DESC)  "DENSE_RANK"
FROM
    (
    SELECT  1 No, '小夫' Name, 90 Score
    FROM DUAL
    UNION ALL
    SELECT 2, '大雄', 30
    FROM DUAL
    UNION ALL
    SELECT 3, '靜香', 90
    FROM DUAL
    UNION ALL
    SELECT 4, '小杉', 100
    FROM DUAL
    UNION ALL    
    SELECT 5, '胖虎', 50
    FROM DUAL
  )
--ORDER BY No  

成績資料中,小夫與靜香為同分(名),以比較次序函數使用上之差異,及對查詢結果影響。
1.  ROW_NUMBER
將按分數產生1~5不重複之流水序號。但由於小夫與靜香為同分,此情況下則排名不具決定性。
2.  RANK函數
對同分二人配發同一序號,依定義將產生跳號
3.  DENSE_RANK函數
同分處理與RANK函數相同,但不跳號
4.  資料排序改變

資料使用不會更動順序的UNION ALL集合(SET)運算指令創建,如未指定排序條件情況下,查詢結果將被分析函數的排序設定所影響。

SELECT No
     , Name
     , Score
     , ROW_NUMBER() OVER (ORDER BY Score DESC) "ROW_NUMBER"
     , RANK() OVER (ORDER BY Score DESC)        "RANK"
     , DENSE_RANK() OVER (ORDER BY Score DESC)  "DENSE_RANK"
FROM
    (VALUES(1, '小夫',  90)
         , (2, '大雄',  30)
         , (3, '靜香',  90)
         , (4, '小杉', 100)
         , (5, '胖虎',  50)
       ) Math (No, Name, Score)
--ORDER BY No  

排序定義次序函數必要參考項目(ORDER BY子句),但些許情況下,並無任何欄位可供或無法(如:依資料位置)指定,可參考《如何無任何適當ORDER BY欄位情況下,使用ROW_NUMBER函數》文章所探討。

沒有留言:

張貼留言