對hive sql window function的理解與商業應用
why window function
視窗函式可以根據over()後的子句使用函式,可以理解為over會給每個要計算的欄開一口,定義作用範圍,對查詢的結果多出一列,這一列可以是聚合值,也可以是排序值。比起group by更靈活,當需要根據不同分割槽進行計算時,分析函式即可使用。
語法
over後面寫要作用的範圍,格式如下:
(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
若不寫的話預設為整個範圍。即:rows between unbounded preceding and unbounded following
通常會根據排序計算,因此會在後方加入排序函式。如
果over()子句中接order by,例如:over(order by date),
則預設的開窗範圍為根據date排序後的第一行到當前行,rows between unbounded preceding and current row。
在視窗函式中使用分組的結果來分析,使用partition by + order by
例:
--統計每天u_id的vv大盤佔比 select u_id, p_date, vv, vv/sum(vv) over(partition by p_date) from table
例:取前20%頭部視訊使用NTILE分析函式,把所有vv分為5份,為1的哪一份就是我們想要的結果.
--取前20%頭部視訊
select id, p_date, vv
,ntile(5) over(partition by p_date order by vv deac) as top20
from photo_table;
select id, p_date, sum(vv)
,ntile(5) over(order by sum(vv) deac) as top20
from photo_table
group by id, p_date;
例:計算累計和
根據月份排序,給出每個月份的視訊觀看數以及累計到當月的視訊觀看數。
select id, month, sum(vv)
,sum(sum(vv)) over(order by month) as acumulative_vv--這裡共聚合了兩次
from photo_table
group by month
order by month;
附錄
有些地方在子句當中使用分組時會用distribute by,我個人理解與partition by其實無本質上的區別,只是要注意搭配的排序函式。
patition by是按照一個一個reduce去處理資料的,所以要使用全域性排序order by
而distribute by是按照多個reduce去處理資料的,所以對應的排序是區域性排序sort by
另外,我還看到有其他同學遇到更負責的情況,如在要求同一個客戶下,取卡稽核日期小的卡,若卡稽核日期相同,取卡申請id小的卡,若卡申請id相同,則取卡種和卡申請時卡種相同的卡。
這時候在條件裡要寫:
select *
from (
select row_number() over(partition by id order by create_date, apply_id, case when produce=cardtype then '1'end ) as rk
from custom_tb
)tb1
where tb1.rk=1