文章目錄
over子句介紹
over子句參考鏈接 https://blog.csdn.net/czr11616/article/details/101645693
1. 什麼是over子句
我們可以形象的把over()子句理解成開窗子句,即打開一個窗口,窗口內包含多條記錄,over()會給每一行開一個窗口。如下圖,總共有5條記錄,每一行代表一條記錄,over()在每一條記錄的基礎上打開一個窗口,給r1記錄打開w1窗口,窗口內只包含自己,給r2打開w2窗口,窗口內包含r1、r2,給r3打開w3窗口,窗口內包含r1、r2、r3,以此類推…
由上我們不難發現,在使用over()子句進行查詢的時候, 不僅可以查詢到每條記錄的信息,還可以查詢到這條記錄對應窗口內的所有記錄的聚合信息,所以我們通常結合聚合函數和over()子句一起使用。
那麼over()是如何進行開窗的呢?即每條記錄對應的窗口內應該包含哪些記錄呢?這些都是在over()子句的括號內進行定義。
2. over子句的開窗範圍
- current row代表查詢的當前行
- 1 preceding代表前一行
- 1 following代表後一行
- unbounded preceding代表第一行
- unbounded following代表最後一行。
(注意這裏的第一行和最後一行並不是嚴格的第一行和最後一行,根據具體情況而定)
3. window clause
over()子句的開窗範圍可以通過window 子句(window clause)在over()的括號中定義,window clause的規範如下:
(ROWS | RANGE) BETWEEN (UNBOUNDED | [num]) PRECEDING AND ([num] PRECEDING | CURRENT ROW | (UNBOUNDED | [num]) FOLLOWING)
(ROWS | RANGE) BETWEEN CURRENT ROW AND (CURRENT ROW | (UNBOUNDED | [num]) FOLLOWING)
(ROWS | RANGE) BETWEEN [num] FOLLOWING AND (UNBOUNDED | [num]) FOLLOWING
例如 :
select *,sum(column_name) over( rows between unbounded preceding and unbounded following) from table_name
表示查詢每一行的所有列值,同時給每一行打開一個從第一行到最後一行的窗口,並統計窗口內所有記錄的column_name列值的和。最後給每一行輸出該行的所有屬性以及該行對應窗口內記錄的聚合值。
4. over子句默認值
如果over()子句中什麼都不寫的話,默認開窗範圍是:rows between unbounded preceding and unbounded following
4.1 order by
如果over()子句中接order by,例如:over(order by date),
則默認的開窗範圍爲根據date排序後的rows between unbounded preceding and current row,
即第一行到當前行,
意思是over(order by date)和over(order by date rows between unbounded preceding and current row)的效果是一樣的。
4.2 partition by
如果over子句中接partition by(和group by類似,都是根據列值對行進行分組),
例如over(partition by month(date)),
則每一行的默認的開窗範圍爲當前行所在分組的所有記錄。
注意partition by子句不能單獨和window clause子句一起使用,必須結合order by子句,下面會討論。
4.3 partition by + order by
先分組,再排序,即組內排序。
同樣的,如果 order by後不接window clause,則每一行的默認的開窗範圍爲:當前行所在分組的第一行到當前行,
即over(partition by (month(date)) order by orderdate)和over(partition by (month(date)) order by orderdate rows between undounded preceding and current row)是一樣的。
幾個常用開窗函數
案例引出
有學生信息表:
hive> select * from stu_managed;
OK
1 張三dg un 23 IS
95002 劉晨 女 19 IS
95017 王風娟 女 18 IS
95018 王一 女 19 IS
95013 馮偉 男 21 CS
95014 王小麗 女 19 CS
95019 邢小麗 女 19 IS
95020 趙錢 男 21 IS
95003 王敏 女 22 MA
95004 張立 男 19 IS
95012 孫花 女 20 CS
95010 孔小濤 男 19 CS
95005 劉剛 男 18 MA
95006 孫慶 男 23 CS
95007 易思玲 女 19 MA
95008 李娜 女 18 CS
95021 週二 男 17 MA
95022 鄭明 男 20 MA
95001 李勇 男 20 CS
95011 包小柏 男 18 MA
95009 夢圓圓 女 18 MA
95015 王君 男 18 MA
求:學生信息表中 每個部門中年齡最大的前兩個
分析:
將數據按照部門分組
在在每一個部門中進行局部排序 倒序
每個部門中輸出2個
直接寫比較困難,藉助分析函數
窗口函數+over子句
over子句: 用於指定分組(分區)或排序規則的 行號|排名規則
#over子句中的語法:
over(distribute by + sort by )
over(partition by + order by )
row_number
-
對學生信息數據 按照部門分 在每個部門中加行號
hive> select > dept,name,row_number() over(distribute by dept) > from stu_managed; Total MapReduce CPU Time Spent: 0 msec OK CS 孫慶 1 CS 馮偉 2 CS 王小麗 3 CS 李勇 4 CS 孫花 5 CS 孔小濤 6 CS 李娜 7 IS 張三dg 1 IS 張立 2 IS 趙錢 3 IS 邢小麗 4 IS 王一 5 IS 王風娟 6 IS 劉晨 7 MA 夢圓圓 1 MA 王君 2 MA 易思玲 3 MA 劉剛 4 MA 週二 5 MA 鄭明 6 MA 包小柏 7 MA 王敏 8 Time taken: 1.959 seconds, Fetched: 22 row(s)
-
相對每一個部門的每個人的年齡排序
hive> select > dept,name,age,row_number() over(distribute by dept sort by age desc) > from stu_managed; Total MapReduce CPU Time Spent: 0 msec OK CS 孫慶 23 1 CS 馮偉 21 2 CS 李勇 20 3 CS 孫花 20 4 CS 王小麗 19 5 CS 孔小濤 19 6 CS 李娜 18 7 IS 張三dg 23 1 IS 趙錢 21 2 IS 王一 19 3 IS 劉晨 19 4 IS 張立 19 5 IS 邢小麗 19 6 IS 王風娟 18 7 MA 王敏 22 1 MA 鄭明 20 2 MA 易思玲 19 3 MA 夢圓圓 18 4 MA 包小柏 18 5 MA 劉剛 18 6 MA 王君 18 7 MA 週二 17 8
rank
- 在每個部門中按照年齡進行添加排名
hive> select
> dept,name,age,rank() over(partition by dept order by age)
> from stu_managed;
Total MapReduce CPU Time Spent: 0 msec
OK
CS 李娜 18 1
CS 孔小濤 19 2
CS 王小麗 19 2
CS 李勇 20 4
CS 孫花 20 4
CS 馮偉 21 6
CS 孫慶 23 7
IS 王風娟 18 1
IS 張立 19 2
IS 劉晨 19 2
IS 王一 19 2
IS 邢小麗 19 2
IS 趙錢 21 6
IS 張三dg 23 7
MA 週二 17 1
MA 劉剛 18 2
MA 包小柏 18 2
MA 夢圓圓 18 2
MA 王君 18 2
MA 易思玲 19 6
MA 鄭明 20 7
MA 王敏 22 8
dense_rank
dense_rank 與 rank的區別是不會累加並列
hive> select dept,name,age,dense_rank() over(partition by dept order by age) from stu_managed;
Total MapReduce CPU Time Spent: 0 msec
OK
CS 李娜 18 1
CS 孔小濤 19 2
CS 王小麗 19 2
CS 李勇 20 3
CS 孫花 20 3
CS 馮偉 21 4
CS 孫慶 23 5
IS 王風娟 18 1
IS 張立 19 2
IS 劉晨 19 2
IS 王一 19 2
IS 邢小麗 19 2
IS 趙錢 21 3
IS 張三dg 23 4
MA 週二 17 1
MA 劉剛 18 2
MA 包小柏 18 2
MA 夢圓圓 18 2
MA 王君 18 2
MA 易思玲 19 3
MA 鄭明 20 4
MA 王敏 22 5
row_number rank dense_rank 使用場景:結合over子句 MR中分組求topN
案例答案
hive> select * from (select dept,name,age,row_number() over(distribute by dept sort by age desc) index from stu_managed) a where index<=2;
Total MapReduce CPU Time Spent: 0 msec
OK
CS 孫慶 23 1
CS 馮偉 21 2
IS 張三dg 23 1
IS 趙錢 21 2
MA 王敏 22 1
MA 鄭明 20 2