詳解Hive窗口函數實際應用
LAG的使用:
LAG(col,n,DEFAULT) 用于統計窗口內往上第n行值。
第一個參數為列名,第二個參數為往上第n行(可選,默認為1),第三個參數為默認值(當往上第n行為NULL時候,取默認值,如不指定,則為NULL)
SELECT cookieid,
createtime,
url,
ROW_NUMBER() OVER(PARTITION BY cookieid ORDER BY createtime) AS rn,
LAG(createtime,1,'1970-01-01 00:00:00') OVER(PARTITION BY cookieid ORDER BY createtime) AS last_1_time,
LAG(createtime,2) OVER(PARTITION BY cookieid ORDER BY createtime) AS last_2_time
FROM user_url;
結果如下:

解釋:
last_1_time: 指定了往上第1行的值,default為'1970-01-01 00:00:00'
cookie1第一行,往上1行為NULL,因此取默認值 1970-01-01 00:00:00
cookie1第三行,往上1行值為第二行值,2021-06-10 10:00:02
cookie1第六行,往上1行值為第五行值,2021-06-10 10:50:01
last_2_time: 指定了往上第2行的值,為指定默認值
cookie1第一行,往上2行為NULL
cookie1第二行,往上2行為NULL
cookie1第四行,往上2行為第二行值,2021-06-10 10:00:02
cookie1第七行,往上2行為第五行值,2021-06-10 10:50:01
LEAD的使用:
與LAG相反
LEAD(col,n,DEFAULT) 用于統計窗口內往下第n行值。
第一個參數為列名,第二個參數為往下第n行(可選,默認為1),第三個參數為默認值(當往下第n行為NULL時候,取默認值,如不指定,則為NULL)
SELECT cookieid,
createtime,
url,
ROW_NUMBER() OVER(PARTITION BY cookieid ORDER BY createtime) AS rn,
LEAD(createtime,1,'1970-01-01 00:00:00') OVER(PARTITION BY cookieid ORDER BY createtime) AS next_1_time,
LEAD(createtime,2) OVER(PARTITION BY cookieid ORDER BY createtime) AS next_2_time
FROM user_url;
結果如下:

FIRST_VALUE的使用:
取分組內排序后,截止到當前行,第一個值。
SELECT cookieid,
createtime,
url,
ROW_NUMBER() OVER(PARTITION BY cookieid ORDER BY createtime) AS rn,
FIRST_VALUE(url) OVER(PARTITION BY cookieid ORDER BY createtime) AS first1
FROM user_url;
結果如下:

LAST_VALUE的使用:
取分組內排序后,截止到當前行,最后一個值。
SELECT cookieid,
createtime,
url,
ROW_NUMBER() OVER(PARTITION BY cookieid ORDER BY createtime) AS rn,
LAST_VALUE(url) OVER(PARTITION BY cookieid ORDER BY createtime) AS last1
FROM user_url;
結果如下:

如果想要取分組內排序后最后一個值,則需要變通一下:
SELECT cookieid,
createtime,
url,
ROW_NUMBER() OVER(PARTITION BY cookieid ORDER BY createtime) AS rn,
LAST_VALUE(url) OVER(PARTITION BY cookieid ORDER BY createtime) AS last1,
FIRST_VALUE(url) OVER(PARTITION BY cookieid ORDER BY createtime DESC) AS last2
FROM user_url
ORDER BY cookieid,createtime;
注意上述SQL,使用的是 FIRST_VALUE 的倒序取出分組內排序最后一個值!
結果如下:

此處要特別注意order by
如果不指定ORDER BY,則進行排序混亂,會出現錯誤的結果
SELECT cookieid,
createtime,
url,
FIRST_VALUE(url) OVER(PARTITION BY cookieid) AS first2
FROM user_url;
結果如下:

上述 url2 和 url55 的createtime即不屬于最靠前的時間也不屬于最靠后的時間,所以結果是混亂的。
4. CUME_DIST
先創建一張員工薪水表:staff_salary
CREATE EXTERNAL TABLE staff_salary (
dept string,
userid string,
sal int
);
表中加入如下數據:
d1,user1,1000
d1,user2,2000
d1,user3,3000
d2,user4,4000
d2,user5,5000
CUME_DIST的使用:
此函數的結果和order by的排序順序有關系。
CUME_DIST:小于等于當前值的行數/分組內總行數。 order默認順序:正序
比如,統計小于等于當前薪水的人數,所占總人數的比例。
SELECT
dept,
userid,
sal,
CUME_DIST() OVER(ORDER BY sal) AS rn1,
CUME_DIST() OVER(PARTITION BY dept ORDER BY sal) AS rn2
FROM staff_salary;
結果如下:

解釋:
rn1: 沒有partition,所有數據均為1組,總行數為5,
第一行:小于等于1000的行數為1,因此,1/5=0.2
第三行:小于等于3000的行數為3,因此,3/5=0.6
rn2: 按照部門分組,dpet=d1的行數為3,
第二行:小于等于2000的行數為2,因此,2/3=0.6666666666666666
請輸入評論內容...
請輸入評論/評論長度6~500個字
最新活動更多
- 1 AI狂歡遇上油價破百,全球股市還能漲多久? | 產聯看全球
- 2 OpenAI深夜王炸!ChatGPT Images 2.0實測:中文穩、細節炸,設計師慌了
- 3 6000億美元估值錨定:字節跳動的“去單一化”突圍與估值重構
- 4 Tesla AI5芯片最新進展總結
- 5 連夜測了一波DeepSeek-V4,我發現它可能只剩“審美”這個短板了
- 6 熱點丨AI“瑜亮之爭”:既生OpenClaw,何生Hermes?
- 7 AI界的殺豬盤:9秒刪庫跑路,全員被封號,還繼續扣錢!
- 8 2026,人形機器人只贏了面子
- 9 DeepSeek降價90%:價格屠夫不是身份,是戰略
- 10 AI Infra產業鏈卡在哪里了?


分享













