SUM--
sum(匯總字段) over (partition by 分組字段 order by 排序字段)
如果不指定ROWS BETWEEN,默認為從起點到當前行;
如果不指定ORDER BY,則將分組內所有值累加;
關鍵是理解ROWS BETWEEN含義,也叫做WINDOW子句:
PRECEDING:往前
FOLLOWING:往后
CURRENT ROW:當前行
UNBOUNDED:起點,
UNBOUNDED PRECEDING 表示從前面的起點,
UNBOUNDED FOLLOWING:表示到后面的終點
–其他AVG,MIN,MAX,和SUM用法一樣。
select cookieid, createtime, pv, sum(pv) over (partition by cookieid order by createtime rows between unbounded preceding and current row) as pv1, sum(pv) over (partition by cookieid order by createtime) as pv2, sum(pv) over (partition by cookieid) as pv3, sum(pv) over (partition by cookieid order by createtime rows between 3 preceding and current row) as pv4, sum(pv) over (partition by cookieid order by createtime rows between 3 preceding and 1 following) as pv5, sum(pv) over (partition by cookieid order by createtime rows between current row and unbounded following) as pv6 from cookie1;
pv1: 分組內從起點到當前行的pv累積,如,11號的pv1=10號的pv+11號的pv, 12號=10號+11號+12號 pv2: 同pv1 pv3: 分組內(cookie1)所有的pv累加 pv4: 分組內當前行+往前3行,如,11號=10號+11號, 12號=10號+11號+12號, 13號=10號+11號+12號+13號, 14號=11號+12號+13號+14號 pv5: 分組內當前行+往前3行+往后1行,如,14號=11號+12號+13號+14號+15號=5+7+3+2+4=21 pv6: 分組內當前行+往后所有行,如,13號=13號+14號+15號+16號=3+2+4+4=13,14號=14號+15號+16號=2+4+4=10
NTILE,ROW_NUMBER,RANK,DENSE_RANK
NTILE(n) 用於將分組數據按照順序切分成n片,返回當前切片值
NTILE不支持ROWS BETWEEN,比如 NTILE(2) OVER(PARTITION BY cookieid ORDER BY createtime ROWS BETWEEN 3 PRECEDING AND CURRENT ROW)
如果切片不均勻,默認增加第一個切片的分布
例子:
有下圖的1000家店鋪的價格數據。我們想知道,價格排名前30%的店鋪的平均價格,和后70%的。

思路:
把店鋪均勻的按價格遞減順序分成10片。然后取切片數=1,2,3的即為前30%。
sql:
-- 1 把記錄按價格順序拆分成10片
drop table if exists test_dp_price_rk;
create table test_dp_price_rk
as
select
id,
price,
NTILE(10) OVER (order by price desc) as rn
from test_dp_price;
-- 2 按片取30%和70%,分別計算平均值
select
new_rn,
max(case when new_rn=1 then 'avg_price_first_30%' when new_rn=2 then 'avg_price_last_70%' end) as avg_price_name,
avg(price) avg_price
from
(
select
id,
price,
rn,
case when rn in (1,2,3) then 1 else 2 end as new_rn
from test_dp_price_rk
)a
group by new_rn;
ROW_NUMBER()
ROW_NUMBER() –從1開始,按照順序,生成分組內記錄的序列
–比如,按照pv降序排列,生成分組內每天的pv名次
ROW_NUMBER() 的應用場景非常多,再比如,獲取分組內排序第一的記錄;獲取一個session中的第一條refer等。
select row_number() over (partition by cookieid order by piv desc) as rn from table;
—RANK() 生成數據項在分組中的排名,排名相等會在名次中留下空位
—DENSE_RANK() 生成數據項在分組中的排名,排名相等會在名次中不會留下空位
select cookieid, createtime, pv, rank() over (partition by cookieid order by pv desc) as rn1, dense_rank() over (partition by cookieid order by pv desc) as rn2, row_number() over (partition by cookieid order by pv desc) as rn3 from cookie.cookie2 where cookieid='cookie1';
row_number: 按順序編號,不留空位
rank: 按順序編號,相同的值編相同號,留空位
dense_rank: 按順序編號,相同的值編相同的號,不留空位
–CUME_DIST :小於等於當前值的行數/分組內總行數
比如,統計小於等於當前薪水的人數,所占總人數的比例
select dept, userid, sal, cume_dist() over (order by sal) as rn1, cume_dist() over (partition by dept order by sal) as rn2 from cookie.cookie3;

–PERCENT_RANK :分組內當前行的RANK值-1/分組內總行數-1
由於Hive 中的ORDER BY 對於大數據集 存在性能問題,
延伸出了部分排序,以及將按相同KEY 控制到同一划分集合的需求。
即以下兩個方案 SORT BY , DISTRIBUTE BY, 我們分別對這兩個方案進行介紹。
sort by
SORT BY 是一個部分排序方案, 其只會在每個reducer 中對數據進行排序,
也就是執行一個局部排序過程。
使用sort by 你可以指定執行的reduce 個數 (set mapred.reduce.tasks=<number>),
對輸出的數據再執行歸並排序,即可以得到全部結果。
distribute by
DISTRIBUTE BY 控制map 中的輸出在 reducer 中是如何進行划分的。
使用DISTRIBUTE BY 可以保證相同KEY的記錄被划分到一個Reduce 中。
cluster by 當sort by 和 distribute by 用到同一個字段 時 用 cluster by 代替
使用sort by 你可以指定執行的reduce 個數 (set mapred.reduce.tasks=<number>),
對輸出的數據再執行歸並排序,即可以得到全部結果。

