1. 程式人生 > >【hive】分組求排名

【hive】分組求排名

分組求排名

  • 相信好多使用Mysql的使用者一定對分組求排名的需求感到發怵.
  • 但是在hive或者oracle來說就能簡單實現.
  • 採用視窗函式:rank() over() / row_number() over() / dense_rank() over()函式就能輕鬆完成.

視窗函式

  • 我們可以理解為我們先把需要分析的欄位select出來,然後通過視窗函式進行分析.
  • 所以視窗函式產生的結果一定是一對一的,即便在視窗中使用分組操作產生相同的值也每行資料都有.

示例

select 
    user_id,user_type,sales, --視窗函式的分析欄位
    RANK() over (partition by user_type order by sales desc) as rank,
    ROW_NUMBER() over (partition by user_type order by sales desc) as row_number,
    DENSE_RANK() over (partition by user_type order by sales desc) as dense_rank
from
    order_detail; 
  • 根據視窗函式的理解,我們來看上述例子
    • 要分析的欄位有 user_type,sales,執行過程對這些欄位select出來(可能select不太準確,但是要先取得這些要用於分析的欄位)
    • 使用視窗函式進行分析 over() 是視窗函式,over()裡面一般要寫partition by 和 order by來對分析的資料進行分組和排序
    • over() 函式前邊要定義分析策略,比如 rank(), row_number(),dense_rank()都是不同的分析策略.

結果

user_id user_type sales rank row_number dense_rank
wutong new 6 1 1 1
qishili new 5 2 2 2
lilisi new 5 2 3 2
wanger new 3 4 4 3
zhangsa new 2 5 5 4
qibaqiu new 1 6 6 5
liiu new 1 6 7 5
liwei old 3 1 1 1
wangshi old 2 2 2 2
lisi old 1 3 3 3
  • 如上述表格,rank() / row_number() / dense_rank() 都是進行排名.
    • rank()在處理相同排名的時候根據同排名資料數量進行順延排名
    • dense_rank()在處理相同排名的時候不會順延排名
    • row_number()如函式名,就是單單是排名後的行數

HIVE2.10以後over()函式支援對聚合函式的支援

SELECT rank() OVER (ORDER BY sum(b))
FROM table
GROUP BY a;

上面等於於

SELECT sum_b rank() OVER (ORDER BY sum_b)
FROM(
    SELECT SUM(b) AS sum_b
    FROM table
    GROUP BY a
) t;