成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

聊聊Hive常見的分析函數

大數據
dense_rank函數的功能與rank函數類似,dense_rank函數在生成序號時是連續的,而rank函數生成的序號有可能不連續。當出現名次相同時,則排名序號也相同。而下一個排名的序號與上一個排名序號是連續的。

[[402112]]

本文轉載自微信公眾號「大數據技術與數倉」,作者西貝。轉載本文請聯系大數據技術與數倉公眾號。

 1.基本語法

  1. Function (arg1,..., argn) OVER ([PARTITION BY <...>] [ORDER BY <....>] 
  2. [<window_expression>]) 

Function (arg1,..., argn) 可以是下面的四類函數:

  • Aggregate Functions: 聚合函數,比如:sum(...)、 max(...)、min(...)、avg(...)等
  • Sort Functions: 數據排序函數, 比如 :rank(...)、row_number(...)等
  • Analytics Functions: 統計和比較函數, 比如:lead(...)、lag(...)、 first_value(...)等

2.數據準備

樣例數據

  1. [職工姓名|部門編號|職工ID|工資|崗位類型|入職時間] 
  2. Michael|1000|100|5000|full|2014-01-29 
  3. Will|1000|101|4000|full|2013-10-02 
  4. Wendy|1000|101|4000|part|2014-10-02 
  5. Steven|1000|102|6400|part|2012-11-03 
  6. Lucy|1000|103|5500|full|2010-01-03 
  7. Lily|1001|104|5000|part|2014-11-29 
  8. Jess|1001|105|6000|part|2014-12-02 
  9. Mike|1001|106|6400|part|2013-11-03 
  10. Wei|1002|107|7000|part|2010-04-03 
  11. Yun|1002|108|5500|full|2014-01-29 
  12. Richard|1002|109|8000|full|2013-09-01 

建表語句:

  1. CREATE TABLE IF NOT EXISTS employee ( 
  2. name string, 
  3. dept_num int
  4. employee_id int
  5. salary int
  6. type string, 
  7. start_date date 
  8. ROW FORMAT DELIMITED 
  9. FIELDS TERMINATED BY '|' 
  10. STORED as TEXTFILE; 

加載數據

  1. load data local inpath '/opt/datas/data/employee_contract.txt' into table employee; 

3.窗口聚合函數

(1)查詢姓名、部門編號、工資以及部門人數

  1. select  
  2.     name
  3.     dept_num as deptno , 
  4.     salary, 
  5.     count(*) over (partition by dept_num) as cnt  
  6. from employee ; 

結果輸出:

  1. name    deptno  salary  cnt 
  2. Lucy    1000    5500    5 
  3. Steven  1000    6400    5 
  4. Wendy   1000    4000    5 
  5. Will    1000    4000    5 
  6. Michael 1000    5000    5 
  7. Mike    1001    6400    3 
  8. Jess    1001    6000    3 
  9. Lily    1001    5000    3 
  10. Richard 1002    8000    3 
  11. Yun     1002    5500    3 
  12. Wei     1002    7000    3 

(2)查詢姓名、部門編號、工資以及每個部門的總工資,部門總工資按照降序輸出

  1. select  
  2.     name , 
  3.     dept_num as deptno, 
  4.     salary, 
  5.     sum(salary) over (partition by dept_num order by dept_num) as sum_dept_salary  
  6. from employee  
  7. order by sum_dept_salary desc

結果輸出:

  1. name    deptno  salary  sum_dept_salary 
  2. Michael 1000    5000    24900 
  3. Will    1000    4000    24900 
  4. Wendy   1000    4000    24900 
  5. Steven  1000    6400    24900 
  6. Lucy    1000    5500    24900 
  7. Wei     1002    7000    20500 
  8. Yun     1002    5500    20500 
  9. Richard 1002    8000    20500 
  10. Lily    1001    5000    17400 
  11. Jess    1001    6000    17400 
  12. Mike    1001    6400    17400 

4.窗口排序函數

簡介

窗口排序函數提供了數據的排序信息,比如行號和排名。在一個分組的內部將行號或者排名作為數據的一部分進行返回,最常用的排序函數主要包括:

row_number:根據具體的分組和排序,為每行數據生成一個起始值等于1的唯一序列數

rank:對組中的數據進行排名,如果名次相同,則排名也相同,但是下一個名次的排名序號會出現不連續。比如查找具體條件的topN行

dense_rank:dense_rank函數的功能與rank函數類似,dense_rank函數在生成序號時是連續的,而rank函數生成的序號有可能不連續。當出現名次相同時,則排名序號也相同。而下一個排名的序號與上一個排名序號是連續的。

percent_rank:排名計算公式為:(current rank - 1)/(total number of rows - 1)

ntile:將一個有序的數據集劃分為多個桶(bucket),并為每行分配一個適當的桶數。它可用于將數據劃分為相等的小切片,為每一行分配該小切片的數字序號。

(1)查詢姓名、部門編號、工資、排名編號(按工資的多少排名)

  1. select  
  2.    name , 
  3.    dept_num as dept_no , 
  4.    salary, 
  5.    row_number() over (order by salary desc ) rnum  
  6. from employee; 

結果輸出:

  1. name    dept_no salary  rnum 
  2. Richard 1002    8000    1 
  3. Wei     1002    7000    2 
  4. Mike    1001    6400    3 
  5. Steven  1000    6400    4 
  6. Jess    1001    6000    5 
  7. Yun     1002    5500    6 
  8. Lucy    1000    5500    7 
  9. Lily    1001    5000    8 
  10. Michael 1000    5000    9 
  11. Wendy   1000    4000    10 
  12. Will    1000    4000    11 

(2)查詢每個部門工資最高的兩個人的信息(姓名、部門、薪水)

  1. select  
  2.    name
  3.    dept_num, 
  4.    salary  
  5. from 
  6.  select name , 
  7.    dept_num , 
  8.    salary, 
  9.    row_number() over (partition by dept_num order by salary desc ) rnum  
  10.  from employee) t1 
  11.  where rnum <= 2; 

結果輸出:

  1. name    dept_num        salary 
  2. Steven  1000    6400 
  3. Lucy    1000    5500 
  4. Mike    1001    6400 
  5. Jess    1001    6000 
  6. Richard 1002    8000 
  7. Wei     1002    7000 

(3)查詢每個部門的員工工資排名信息

  1. select 
  2.  name , 
  3.  dept_num as dept_no , 
  4.  salary,row_number() over (partition by dept_num order by salary desc ) rnum  
  5. from employee; 

結果輸出:

  1. name    dept_no salary  rnum 
  2. Steven  1000    6400    1 
  3. Lucy    1000    5500    2 
  4. Michael 1000    5000    3 
  5. Wendy   1000    4000    4 
  6. Will    1000    4000    5 
  7. Mike    1001    6400    1 
  8. Jess    1001    6000    2 
  9. Lily    1001    5000    3 
  10. Richard 1002    8000    1 
  11. Wei     1002    7000    2 
  12. Yun     1002    5500    3 

(4)使用rank函數進行排名

  1. select 
  2.   name
  3.   dept_num, 
  4.   salary, 
  5.   rank() over (order by salary desc) rank 
  6. from employee; 

結果輸出:

  1. name    dept_num        salary  rank 
  2. Richard 1002    8000    1 
  3. Wei     1002    7000    2 
  4. Mike    1001    6400    3 
  5. Steven  1000    6400    3 
  6. Jess    1001    6000    5 
  7. Yun     1002    5500    6 
  8. Lucy    1000    5500    6 
  9. Lily    1001    5000    8 
  10. Michael 1000    5000    8 
  11. Wendy   1000    4000    10 
  12. Will    1000    4000    10 

(5)使用dense_rank進行排名

  1. select 
  2.   name
  3.   dept_num, 
  4.   salary, 
  5.   dense_rank() over (order by salary desc) rank 
  6. from employee; 

結果輸出:

  1. name    dept_num        salary  rank 
  2. Richard 1002    8000    1 
  3. Wei     1002    7000    2 
  4. Mike    1001    6400    3 
  5. Steven  1000    6400    3 
  6. Jess    1001    6000    4 
  7. Yun     1002    5500    5 
  8. Lucy    1000    5500    5 
  9. Lily    1001    5000    6 
  10. Michael 1000    5000    6 
  11. Wendy   1000    4000    7 
  12. Will    1000    4000    7 

(6)使用percent_rank()進行排名

  1. select 
  2.   name
  3.   dept_num, 
  4.   salary, 
  5.   percent_rank() over (order by salary desc) rank 
  6. from employee; 

結果輸出:

  1. name    dept_num        salary  rank 
  2. Richard 1002    8000    0.0 
  3. Wei     1002    7000    0.1 
  4. Mike    1001    6400    0.2 
  5. Steven  1000    6400    0.2 
  6. Jess    1001    6000    0.4 
  7. Yun     1002    5500    0.5 
  8. Lucy    1000    5500    0.5 
  9. Lily    1001    5000    0.7 
  10. Michael 1000    5000    0.7 
  11. Wendy   1000    4000    0.9 
  12. Will    1000    4000    0.9 

(7)使用ntile進行數據分片排名

  1. SELECT 
  2. name
  3. dept_num as deptno, 
  4. salary, 
  5. ntile(4) OVER(ORDER BY salary descas ntile 
  6. FROM employee; 

結果輸出:

  1. name    deptno  salary  ntile 
  2. Richard 1002    8000    1 
  3. Wei     1002    7000    1 
  4. Mike    1001    6400    1 
  5. Steven  1000    6400    2 
  6. Jess    1001    6000    2 
  7. Yun     1002    5500    2 
  8. Lucy    1000    5500    3 
  9. Lily    1001    5000    3 
  10. Michael 1000    5000    3 
  11. Wendy   1000    4000    4 
  12. Will    1000    4000    4 

從 Hive v2.1.0開始, 支持在OVER語句里使用聚集函數,比如

  1. SELECT 
  2.   dept_num, 
  3.   row_number() OVER (PARTITION BY dept_num ORDER BY sum(salary)) as rk 
  4. FROM employee 
  5. GROUP BY dept_num; 

結果輸出:

  1. dept_num        rk 
  2. 1000    1 
  3. 1001    1 
  4. 1002    1 

5.窗口分析函數

常用的分析函數主要包括:

  • cume_dist

如果按升序排列,則統計:小于等于當前值的行數/總行數(number of rows ≤ current row)/(total number of rows)。如果是降序排列,則統計:大于等于當前值的行數/總行數。比如,統計小于等于當前工資的人數占總人數的比例 ,用于累計統計。

  • lead(value_expr[,offset[,default]])

用于統計窗口內往下第n行值。第一個參數為列名,第二個參數為往下第n行(可選,默認為1),第三個參數為默認值(當往下第n行為NULL時候,取默認值,如不指定,則為NULL

  • lag(value_expr[,offset[,default]]):

與lead相反,用于統計窗口內往上第n行值。第一個參數為列名,第二個參數為往上第n行(可選,默認為1),第三個參數為默認值(當往上第n行為NULL時候,取默認值,如不指定,則為NULL)

  • first_value: 取分組內排序后,截止到當前行,第一個值
  • last_value

取分組內排序后,截止到當前行,最后一個值

  • (1)統計小于等于當前工資的人數占總人數的比例
  1. SELECT 
  2.  name
  3.  dept_num as deptno, 
  4.  salary, 
  5.  cume_dist() OVER (ORDER BY salary) as cume 
  6. FROM employee; 

結果輸出:

  1. name    deptno  salary  cume 
  2. Wendy   1000    4000    0.18181818181818182 
  3. Will    1000    4000    0.18181818181818182 
  4. Lily    1001    5000    0.36363636363636365 
  5. Michael 1000    5000    0.36363636363636365 
  6. Yun     1002    5500    0.5454545454545454 
  7. Lucy    1000    5500    0.5454545454545454 
  8. Jess    1001    6000    0.6363636363636364 
  9. Mike    1001    6400    0.8181818181818182 
  10. Steven  1000    6400    0.8181818181818182 
  11. Wei     1002    7000    0.9090909090909091 
  12. Richard 1002    8000    1.0 

(2)統計大于等于當前工資的人數占總人數的比例

  1. SELECT 
  2.  name
  3.  dept_num as deptno, 
  4.  salary, 
  5.  cume_dist() OVER (ORDER BY salary descas cume 
  6. FROM employee; 

結果輸出:

  1. name    deptno  salary  cume 
  2. Richard 1002    8000    0.09090909090909091 
  3. Wei     1002    7000    0.18181818181818182 
  4. Mike    1001    6400    0.36363636363636365 
  5. Steven  1000    6400    0.36363636363636365 
  6. Jess    1001    6000    0.45454545454545453 
  7. Yun     1002    5500    0.6363636363636364 
  8. Lucy    1000    5500    0.6363636363636364 
  9. Lily    1001    5000    0.8181818181818182 
  10. Michael 1000    5000    0.8181818181818182 
  11. Wendy   1000    4000    1.0 
  12. Will    1000    4000    1.0 

(3)按照部門統計小于等于當前工資的人數占部門總人數的比例

  1. SELECT 
  2.  name
  3.  dept_num as deptno, 
  4.  salary, 
  5.  cume_dist() OVER (PARTITION BY dept_num ORDER BY salary) as cume 
  6. FROM employee; 

結果輸出:

  1. name    deptno  salary  cume 
  2. Wendy   1000    4000    0.4 
  3. Will    1000    4000    0.4 
  4. Michael 1000    5000    0.6 
  5. Lucy    1000    5500    0.8 
  6. Steven  1000    6400    1.0 
  7. Lily    1001    5000    0.3333333333333333 
  8. Jess    1001    6000    0.6666666666666666 
  9. Mike    1001    6400    1.0 
  10. Yun     1002    5500    0.3333333333333333 
  11. Wei     1002    7000    0.6666666666666666 
  12. Richard 1002    8000    1.0 

(4)按部門分組,統計每個部門員工的工資以及大于等于該員工工資的下一個員工的工資

  1. SELECT 
  2.  name
  3.  dept_num as deptno, 
  4.  salary, 
  5.  lead(salary,1) OVER (PARTITION BY dept_num ORDER BY salary) as lead 
  6. FROM employee; 

結果輸出:

  1. name    deptno  salary  lead 
  2. Wendy   1000    4000    4000 
  3. Will    1000    4000    5000 
  4. Michael 1000    5000    5500 
  5. Lucy    1000    5500    6400 
  6. Steven  1000    6400    NULL 
  7. Lily    1001    5000    6000 
  8. Jess    1001    6000    6400 
  9. Mike    1001    6400    NULL 
  10. Yun     1002    5500    7000 
  11. Wei     1002    7000    8000 
  12. Richard 1002    8000    NULL 

(5)按部門分組,統計每個部門員工的工資以及小于等于該員工工資的上一個員工的工資

  1. SELECT 
  2.  name
  3.  dept_num as deptno, 
  4.  salary, 
  5.  lag(salary,1) OVER (PARTITION BY dept_num ORDER BY salary) as lead 
  6. FROM employee; 

結果輸出:

  1. name    deptno  salary  lead 
  2. Wendy   1000    4000    NULL 
  3. Will    1000    4000    4000 
  4. Michael 1000    5000    4000 
  5. Lucy    1000    5500    5000 
  6. Steven  1000    6400    5500 
  7. Lily    1001    5000    NULL 
  8. Jess    1001    6000    5000 
  9. Mike    1001    6400    6000 
  10. Yun     1002    5500    NULL 
  11. Wei     1002    7000    5500 
  12. Richard 1002    8000    7000 

(6)按部門分組,統計每個部門員工工資以及該部門最低的員工工資

  1. SELECT 
  2.  name
  3.  dept_num as deptno, 
  4.  salary, 
  5.  first_value(salary) OVER (PARTITION BY dept_num ORDER BY salary) as fval 
  6. FROM employee; 

結果輸出:

  1. name    deptno  salary  fval 
  2. Wendy   1000    4000    4000 
  3. Will    1000    4000    4000 
  4. Michael 1000    5000    4000 
  5. Lucy    1000    5500    4000 
  6. Steven  1000    6400    4000 
  7. Lily    1001    5000    5000 
  8. Jess    1001    6000    5000 
  9. Mike    1001    6400    5000 
  10. Yun     1002    5500    5500 
  11. Wei     1002    7000    5500 
  12. Richard 1002    8000    5500 

(7)按部門分組,統計每個部門員工工資以及該部門最高的員工工資

  1. SELECT 
  2.  name
  3.  dept_num as deptno, 
  4.  salary, 
  5.  last_value(salary) OVER (PARTITION BY dept_num ORDER BY salary RANGE 
  6. BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as lval 
  7. FROM employee; 

結果輸出:

  1. name    deptno  salary  lval 
  2. Wendy   1000    4000    6400 
  3. Will    1000    4000    6400 
  4. Michael 1000    5000    6400 
  5. Lucy    1000    5500    6400 
  6. Steven  1000    6400    6400 
  7. Lily    1001    5000    6400 
  8. Jess    1001    6000    6400 
  9. Mike    1001    6400    6400 
  10. Yun     1002    5500    8000 
  11. Wei     1002    7000    8000 
  12. Richard 1002    8000    8000 

注意:last_value默認的窗口是RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW,表示當前行永遠是最后一個值,需改成RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。

img

  • RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW

為默認值,即當指定了ORDER BY從句,而省略了window從句 ,表示從開始到當前行。

  • RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING

表示從當前行到最后一行

  • RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING

表示所有行

  • n PRECEDING m FOLLOWING

表示窗口的范圍是:[(當前行的行數)- n, (當前行的行數)+m]

 

責任編輯:武曉燕 來源: 大數據技術與數倉
相關推薦

2021-09-08 08:55:45

Javascript 高階函數前端

2023-11-28 09:19:12

2022-01-04 06:50:12

數據摘要方法

2022-03-17 08:34:47

TypeScript項目類型

2022-11-30 08:19:15

內存分配Go逃逸分析

2022-03-30 09:01:37

CSS屬性函數

2022-02-07 21:49:19

串行通信UART

2022-09-28 11:34:27

用戶行為數據業務

2020-03-31 09:09:48

Web安全網絡攻擊DDOS

2022-07-07 08:01:51

Python魔法方法代碼

2022-10-17 08:22:28

2020-07-24 10:31:34

未授權訪問漏洞

2022-10-24 00:03:26

GolangNew函數

2021-09-08 06:51:53

CountDownLa閉鎖源碼

2021-03-02 21:52:48

Hive數據類型

2022-08-02 11:29:17

數據分析場景RFM

2023-05-04 00:27:40

2021-06-05 23:39:52

c++函數場景

2022-06-27 15:07:35

智能汽車

2021-04-16 07:19:04

Hive數據類型Hql
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91在线一区二区 | 欧美一级淫片免费视频黄 | 中文字幕 视频一区 | 国产视频一区二区 | av一区二区三区四区 | 日韩在线播放一区 | 在线播放一区 | 亚洲成人福利 | 久久国产精彩视频 | 美女视频h | 天天躁日日躁狠狠很躁 | 国产精品一区二区三区在线 | 中文字幕在线免费观看 | 久久精品国产一区二区电影 | 日日日色| 中文字幕日韩欧美 | 懂色中文一区二区三区在线视频 | 欧美一级特黄aaa大片在线观看 | 国产在线观 | 日韩中文在线视频 | 美日韩中文字幕 | 日日操夜夜操天天操 | 超碰成人免费 | 欧美理论片在线 | 欧美一区二区三区在线免费观看 | 国产精品久久久久久吹潮日韩动画 | 精品国产一区二区三区av片 | 精品综合久久久 | 国精产品一品二品国精在线观看 | 亚洲欧洲中文日韩 | 黄色a三级| 丝袜一区二区三区 | 欧美中文字幕一区二区 | 亚洲精品一区二三区不卡 | 韩国成人在线视频 | 在线色网| 精品一区二区三区91 | 欧美精品中文字幕久久二区 | 看羞羞视频免费 | 亚洲第一天堂无码专区 | 中国人pornoxxx麻豆 |