1. 程式人生 > 資料庫 >對hive sql window function的理解與商業應用

對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