1)定義
視窗函式屬於sql中比較高階的函式
mysql從8.0版本才支援視窗函式,5.6,5.7都沒有視窗函式
oracle 裡面一直支援視窗函式
hive也支援視窗函式
以下函式才是視窗函式
視窗函式(13個):
lead lead(col,n, default_val):往後第n行資料 col 列名 n 往後第幾行 預設為1 預設值 預設null
lag lag(col,n,default_val):往前第n行資料 col 列名 n 往前第幾行 預設為1 預設值 預設null
first_value 在當前視窗下的第乙個值 first_value (col,true/false) 如果設定為true,則跳過空值。
last_value 在當前視窗下的最後乙個值 last_value (col,true/false)如果設定為true,則跳過空值。
標準聚合函式:
分析排名函式
視窗函式=函式+視窗
視窗:函式在運算時,我們可以指定函式運算的資料範圍
2)語法
視窗函式 over([partition by 字段] [order by 字段] [ 視窗語句])
[partition by 字段] [order by 字段] [ 視窗語句]:的含義是可以省略,這三個都可以省略
partition by 給查出來的結果集按照某個字段分割槽,分割槽以後,開窗的大小最大不會超過分割槽資料的大小
一旦分割槽之後,我們必須在單個分區內指定視窗。
order by 給分區內的資料按照某個字段排序
3) 視窗語句
(
rows
| range)
between
(unbounded
|[num]
)preceding
and(
[num]
preceding
|current
row|
(unbounded
|[num]
)following)(
rows
| range)
between
current
rowand
(current
row|
(unbounded
|[num]
)following)(
rows
| range)
between
[num]
following
and(
unbounded
|[num]
)following
兩種特殊情況
當指定order by缺少window子句時,window規範預設為range between unbounded preceding and current row。
如果同時缺少order by和window子句,則window規範預設為row betweenund unbounded preceding和unbounded following。
以下函式在over()裡面只能分割槽和排序,不能自定義視窗大小了,也就是不能再寫window字句
排序分析函式 都不能寫 例如: rank, ntile, denserank, cumedist, percentrank.
lead 和 lag不能寫
需求1 查詢在2023年4月份購買過的顧客及總人數
select
name,
count(1
)over
(rows
between
unbounded
preceding
andunbounded
following
)from business
where
month
(orderdate)=4
group
by name;
由於視窗語句有兩種特殊情況,我們這種剛好符合第二種,因此可以省略掉視窗語句
select
name,
count(1
)over()
from business
where
month
(orderdate)=4
group
by name;
需求2 查詢顧客的購買明細及月購買總額
select
name,
orderdate,
cost,
sum(cost ) over(partition by name,month(orderdate) )
from business;
需求3 上述的場景, 將每個顧客的cost按照日期進行累加
select
name,
orderdate,
cost,
sum(cost)
over
(partition
by name order
by orderdate rows
between
unbounded
preceding
andcurrent
row) cost1,
sum(cost)
over
(partition
by name order
by orderdate) cost2
from business;
需求4 查詢顧客購買明細以及上次的購買時間和下次購買時間
select
name,
orderdate,
cost,
lag(orderdate,1,
'無')
over
(partition
by name order
by orderdate) prev_time,
lead(orderdate,1,
'無')
over
(partition
by name order
by orderdate) next_time
from business;
需求5 查詢顧客每個月第一次的購買時間 和 每個月的最後一次購買時間
注意:last_value和first_value 需要自定義windows字句,否則出現錯誤
select
name,
orderdate,
cost,
first_value(orderdate)
over
(partition
by name,
month
(orderdate)
order
by orderdate rows
between
unbounded
preceding
andunbounded
following
) first_time,
last_value(orderdate)
over
(partition
by name,
month
(orderdate)
order
by orderdate rows
between
unbounded
preceding
andunbounded
following
) last_time
from business;
需求6 查詢前20%時間的訂單資訊
select
t1.*from
(select
name,
orderdate,
cost,
ntile(5)
over
(order
by orderdate ) nsort
from business
) t1
where t1.nsort =
1;
rank() 排序相同時會重複,會跳號
dense_rank() 排序相同時會重複,不會跳號
row_number() 會根據順序計算
select
name,
subject,
score,
rank(
)over
(partition
by subject order
by score desc
) rp,
dense_rank(
)over
(partition
by subject order
by score desc
) drp,
row_number(
)over
(partition
by subject order
by score desc
) rowp
from score;
hive 視窗函式
hive高階函式 row number rank dense rank 這三個視窗函式的使用場景非常多 例子 員工表中,求每個崗位薪水前兩名的員工資訊 name,入職日期,sal row number over partition by job order by sal desc 這個函式會返回組內...
hive視窗函式 Hive sql視窗函式原始碼分析
在了解了視窗函式實現原理 spark hive中視窗函式實現原理覆盤 和 sparksql比hivesql優化的點 視窗函式 之後,今天又擼了一遍hive sql 中視窗函式的原始碼實現,寫個筆記記錄一下。簡單來說,視窗查詢有兩個步驟 將記錄分割成多個分割槽 然後在各個分割槽上呼叫視窗函式。傳統的 ...
Hive視窗函式使用
平常使用 hive最多的是聚合函式 但對於某些偏分析的需求 group by很費力 子查詢很多 這個時候就需要使用視窗分析函式 比如 最近一次行駛里程 select max ded.bill date ded.vin,ded.current milemetre from db.tt repair d...