當前位置:成語大全網 - 書法字典 - 數據分析課程筆記-20-Hive核心技能的窗口功能

數據分析課程筆記-20-Hive核心技能的窗口功能

大家好。在這節課中,我們將學習Hive核心技能中最難的部分——窗口功能。我們之前在學習MySQL的時候學過壹些窗口函數,但是只學了三種排序窗口函數。在本課中,我們將學習更多的窗口函數,包括累積計算、分區排序、切片排序和偏移分析。

在正式學習之前,我們需要明確窗函數和分組的區別。它們在功能上相似,但本質上是不同的。

1.分組將改變表格的結構,但窗口函數不會改變表格的結構。例如,原始表有10行數據,分成兩組後只有兩行,而窗口函數仍然返回十行數據。

2.分組只能查詢分組後的字段,包括分組字段(組名)和聚合函數字段。window函數對查詢字段沒有限制,也就是說,它可以查詢原始表中的任何字段,以及由window函數添加的壹列新值。

好了,現在讓我們壹起進入窗口函數的世界吧~

本節課的主要內容:

1,累積計算窗口函數

(1)sum(……)over(……)

(2)平均(……)超過(……)

③語法總結

2.分區排序窗口函數

(1)行編號()

②排名()

(3)密集秩()

3.切片排序窗口函數

(1)n結束(……)

4.遷移分析窗口功能

5.關鍵練習

在制作報表時,經常會遇到截止到某個月的累計值的計算,通常可以通過EXCEL中的函數來實現。

那麽在HiveSQL中,如何實現這個累計值的計算呢?那就是使用窗口功能!

關於窗口功能的壹些說明:

需求分析:既然要按月累計,那麽首先要將2018中的每筆交易時間轉換為月份並通過分組和聚合進行計算,得到2018中的每月付款金額匯總表,然後使用窗口函數基於此表進行累計計算。

2018月供金額匯總表:

然後使用窗口功能進行每月累積:

年度總結。

這個需求比1的需求多壹個需求,那就是年度總結。然後我們只需要在最後壹個需求的子查詢中添加壹個年份字段。

描述:

Partition by in 1及以上在窗口中起到分組數據的作用。實際上,添加partition by後,可以理解為將其劃分為多個窗口,並在每個窗口中進行累積計算或分區。

如果不按年份添加分區,運行結果將簡單地按月份分組:

2.累積的順序是什麽,升序ASC和降序desc;默認值為升序。

大家在看股票的時候經常會看到這種k線圖,這種k線圖經常被用作7日和30日移動平均線的走勢圖。如何使用窗口函數計算移動平均線?

需求分析:此需求要求每月近三個月的移動平均支付金額。這裏需要用到壹個新的知識點。在窗口函數avg over‘s order by a . month後,添加壹句“Rows between 2 previous and current row”以設置計算移動平均值的範圍。這句話的意思是包括這壹行和前兩行。其他部分的寫法和前面的需求差不多。首先,取出每月支付金額的總和2018,然後使用窗口函數找到移動平均線。

註意:

sum(…A…)over(partition by…B…order by…C…行在…D1…和…D2…之間)

avg(…A…)over(分區依據…B…排序依據…C…d 1…和…D2…之間的行)

答:要處理的字段的名稱

b:分組的字段名

c:排序字段名稱

d:計算的行的範圍

未綁定的前壹行和當前行之間的行

-包括這壹行和所有以前的行。

當前行和未綁定的後續行之間的行

-包括此行和所有後續行。

前3行和當前行之間的行

——包括行內和前三線。

前面3行和後面1行之間的行

——從前三行到下壹行(5行)

max(……)over(partition by……order by……行在……和……之間)

min(……)over(partition by……order by……行在……和……之間)

行數()、秩()、密度秩()

用法:這三個函數的作用是返回對應規則的排序序號。

row _ number()over(partition by…A…order by…B…)

rank()超過(分區依據…A…排序依據…B…)

dense _ rank()over(partition by…A…order by…B…)

a:分組的字段名稱

b:排序字段名稱

註意:這三個函數的括號中沒有字段名!

Row_number:它將為查詢找到的每壹行記錄生成壹個序列號,這些記錄將依次排序,不會重復。

排名與排名。Dense_rank:在每個分組內,rank()是跳躍排序,當有兩個第壹個時,第三個跟隨,而dense_rank()是連續排序,當有兩個第壹個時,第二個仍然跟隨。

示例練習:

再次熟悉user_trade的表結構:

需求分析:先限定時間範圍,然後按user_name分組,分組後選擇user_name,並計算每個用戶的goods_category數量(記得區分重復項),然後用window函數對goods_category數量進行排序。當然,選擇哪種排序方法取決於具體要求。在這裏,我們可以用三種方法來嘗試結果:

註意:窗口函數中的order by字段不能由select中的字段重命名,因為兩者是同時執行的。

需求分析:首先使用窗口函數計算並排序每個用戶在2019年的總支付金額,然後以此為子查詢提取排名為10、20和30的用戶名、總支付金額和排名順序。企業壹般使用dense_rank進行排序,所以我們這裏直接使用dense_rank。

2019每位用戶總支付金額排名:

付款金額在2019中排名為10、20和30的用戶:

分區依據…A…排序依據…B…)

n:分割的切片數量。

a:分組的字段名稱

b:排序字段名稱

需求分析:這個需求非常簡單,只需將需求5第壹步中的排序窗口功能變成切片即可。請註意,時間篩選條件變為2019 1月。

需求分析:前10%,即a * * *分為10組,取1組。因此,讓我們先進行分組:

然後看第壹組:

說明:Lag和Lead分析函數可以提取同壹字段的前n行數據(Lag)和後n行數據(Lead)作為同壹查詢中的獨立列。

在實際應用中,如果要計算今天和昨天的差值,滯後和超前函數的應用尤為重要。當然,這種操作可以通過表自連接來實現,但LAG和LEAD比left join和right join等自連接更高效,SQL語句更簡潔。

lag(exp _ str,offset,defval)over(partion by……order by……)

lead(exp _ str,offset,defval)over(partion by……,order by ……)

lag()函數示例:

lead()函數示例:

需求分析:首先從user_trade表中取出每個用戶的付款時間,將每個用戶放在壹個窗口中,按付款時間排序,並取出offset列:lead(dt,1,dt)over(partition by user _ name order by dt)。然後基於子查詢,篩選出時間間隔大於100天的用戶並計算數量。

註意:如果上面的遷移分析函數寫成lead(dt,1,dt),就沒必要加上下面的dt is not null了,因為如果有默認值,間隔就是0,肯定不滿足條件。

需求分析:

步驟1:兩個表user_trade和user_info用於此需求。前者取支付時間和金額,後者取城市和性別。首先,這兩個表基於用戶名左連接,並取出相應的字段,並按窗口函數排序:

該步驟的運行結果如下:

第二步:取出TOP3:

需求分析:

步驟1:這個需求還使用了兩個表,user_refund和user_info。我們先把每個退款用戶的退款金額和手機品牌拿出來,用窗口功能切片排序,25%分成四塊:

註意:這裏之所以要添加WHERE dt不為null是因為user_refund是壹個分區表,分區表應該限制分區字段,否則hive會報錯。

第二步:選擇前25%,也就是第壹部電影:

最後,添加壹個從hive導出結果數據的命令:

這堂課就到這裏。整個練習下來,我真的掉了半條命。窗口功能確實很難,但掌握方法,多練習,學會拆解需求,循序漸進地做,可以明顯降低難度。希望我以後能用上這麽復雜的技能,哈哈~!