hive中with...as...的用法
阿新 • • 發佈:2020-12-21
with...as...也叫做子查詢部分,語句允許hive定義一個sql片段,供整個sql使用
簡介
with...as...
需要定義一個sql片段,會將這個片段產生的結果集儲存在記憶體中,
後續的sql均可以訪問這個結果集,作用與檢視或臨時表類似.
語法限制
-
with...as...
必須和其他sql一起使用(可以定義一個with
但在後續語句中不使用他) -
with...as...
是一次性的
with...as...
的完整格式是這樣的
-- with table_name as(子查詢語句) 其他sql
with temp as (
select * from xxx
)
select * from temp;
只定義不使用
with temp as (
select * from xxx
)
select * from othertable;
同級的多個temp之間用,
分割with
只需要一次,as
後的子句必須用()
,
with temp1 as (
select * from xxx
),temp2 as (
select * from xxx
)
select * from temp1,temp2;
with...as...
當然是可以巢狀的,此處舉一個簡單例子
with temp2 as (
with temp1 as (
select * from xxx
)
select * from temp1
)
select * from temp2;
with...as...
只能在一條sql中使用
with temp1 as (
select * from xxx
)
select * from temp1;
select xxx from temp1; -- error! no table named temp1;
語句的優點
- 提高程式碼可讀性(結構清晰)
- 簡化sql,優化執行速度(
with
子句只需要執行一次)
栗子
現有city表,結構如下:
city_number | city_name | province |
---|---|---|
010 | 北京 | 北京 |
021 | 上海 | 上海 |
025 | 南京 | 江蘇 |
0512 | 崑山 | 江蘇 |
0531 | 濟南 | 山東 |
0533 | 淄博 | 山東 |
然後分別有商品表good
city_number | good_name |
---|---|
010 | A |
021 | B |
現在需要分別統計
select * from `good` where city_number in (select city_number from city where city_name = "上海");
除了子查詢,上述的的例子還可以用join
來實現,
如果用with...as...語句實現,如下
with tmp_shanghai as(
select city_number from city where city_name = "上海"
)
select * from `good` where tmp_shanghai in (select * from tmp_shanghai)
看起來使用 with...as... 語句反而更復雜一點,但如果tmp_shanghai要被多次使用的使用,就很有必要
來看一個實際的例子,有一張操作表event主要欄位如下:
date | event_key |
---|---|
20190530 | Delete |
20190530 | Put |
20190530 | Get |
20190530 | Get |
20190601 | Set |
......
現在要求一條sql統計出Get
與Set
操作的數量,先使用子查詢實現
select (
select count(*) from event where event_key = "Get"
) as get_num,(
select count(*) from event where event_key = "Set"
) as set_num
如果再增加其他項的統計呢,是否每一個均需要增加一個對event表進行掃描的自查詢
使用with...as...
with temp as(
select * from event where event_key = "Get" or event_key = "Set"
)
select
sum(case when event_key = "Get" then 1 else 0 end) as get_num,
sum(case when event_key = "Set" then 1 else 0 end) as Set_num
from temp
閱讀性是否比之前有所提高?此外,這條語句只對event表進行了一次掃描,將符合條件的資料存入temp中供後續計算,
在event表資料集非常大的情況下,效能將比子查詢的方式優秀很多