MaxCompute SQL中insert語句使用詳情

MaxCompute insert語句使用

本文介紹使用INSERT OVERWRITE和INSERT INTO兩種命令更新表數據,主要內容包括:

  1. insert into table ... values ...語句
  2. insert into/overwrite ... select ...語句
  3. Insert多路輸出(MULTI INSERT)
  4. 輸出到動態分區(DYNAMIC PARTITION)

INSERT VALUES語句

命令使用

INSERT INTO TABLE tablename 
[PARTITION (partcol1=val1, partcol2=val2,...)][(co1name1,colname2,...)] 
[VALUES (col1_value,col2_value,...),(col1_value,col2_value,...),...]
  • tablename:要插入數據的目標表名稱。此名稱需爲已經存在的表名稱。
  • PARTITION (partcol1=val1, partcol2=val2,...)]:分區信息。如果需要更新的表爲分區表,需要指定該參數。
  • [(co1name1,colname2,...):目標表中的字段名稱。
  • col_value:目標表中列對應的列值,多個列值之間用逗號(,)分隔。此列值必須爲常量,列值未指定時,缺省爲NULL。

 

注意:通過VALUES寫入DATETIME、TIMESTAMP類型數據時,需要在VALUES中指定類型名稱,如下所示。 

insert into table srcp (p='abc') values (datetime'2017-11-11 00:00:00',timestamp'2017-11-11 00:00:00.123456789');

1. 特定分區內插入數據:

insert into table sale_detail
partition (sale_date='202003', region='hangzhou')
values ('unique', 'user1', 1000),
  ('adidas', 'user2', 2000),
  ('zara', 'user3', 1500),
  ('veromoda', 'user1', 2000),
  ('nike', 'user4', 1000),
  ('ur', 'user2', 1400),
  ('ochirly', 'user1', 2000),
  ('lily', 'user3', 3000),
  ('onemore', "user2", 1200);

查詢插入數據結果如下:

shop_name	customer_id	total_price	sale_date	region
+----------+------------+------------+----------+-------+
unique	user1	1000.0	202003	hangzhou
adidas	user2	2000.0	202003	hangzhou
zara	user3	1500.0	202003	hangzhou
veromoda	user1	2000.0	202003	hangzhou
nike	user4	1000.0	202003	hangzhou
ur	user2	1400.0	202003	hangzhou
ochirly	user1	2000.0	202003	hangzhou
lily	user3	3000.0	202003	hangzhou
onemore	user2	1200.0	202003	hangzhou

2. 非特定分區插入數據:

insert into table sale_detail
partition (sale_date, region)
  (shop_name, customer_id, total_price, sale_date, region)
values
  ('unique', 'user1', 1000, '202001', 'shanghai'),
  ('adidas', 'user2', 2000, '202001', 'shanghai'),
  ('zara', 'user3', 1500, '202001', 'shanghai');

查詢插入結果:

shop_name	customer_id	total_price	sale_date	region
+----------+------------+------------+----------+-------+
unique	user1	1000.0	202001	shanghai
adidas	user2	2000.0	202001	shanghai
zara	user3	1500.0	202001	shanghai

VALUES TABLE功能

VALUES TABLE並不僅限於在INSERT語句中使用,任何DML語句都可以使用。VALUES TABLE功能的使用方式如下:

  • 在沒有任何物理表時,您可以模擬一個有任意數據的、多行的表,並進行任意運算。

    下例中的values (…), (…) t(a, b)相當於定義了一個名爲t,列爲ab,類型分別爲STRING、BIGINT的表。列的類型需從VALUES列表中推導。

使用示例:

--刪除已存在的表srcp。
drop table if exists srcp;
--創建分區表srcp。
create table if not exists srcp (key string,value bigint) partitioned by (p string);
--爲表srcp中插入數據。
insert into table srcp partition (p) select concat(a,b), length(a)+length(b),'20170102' from values ('d',4),('e',5),('f',6) t(a,b);
--查詢表srcp。
select * from srcp where p='20170102';
+-----+------------+---+
| key | value      | p |
+-----+------------+---+
| d4  | 2          | 20170102 |
| e5  | 2          | 20170102 |
| f6  | 2          | 20170102 |
+-----+------------+---

INSERT into/overwrite語句

在MaxCompute SQL處理數據的過程中,INSERT OVERWRITE/INTO用於將計算的結果保存目標表中。

  • insert into:直接向表或表的分區中追加數據。不支持INSERT INTO到Hash Clustering表。如果您需要插入少量測試數據,可以配合VALUES語句使用。
  • insert overwrite:先清空表中的原有數據,再向表或分區中插入數據。目前INSERT OVERWRITE不支持指定插入列的功能,暫時只能用INSERT INTO
INSERT OVERWRITE|INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)] [(col1,col2 ...)]
select_statement
FROM from_statement;
  • tablename:需要插入數據的目標表名稱。
  • PARTITION (partcol1=val1, partcol2=val2 ...):需要插入數據的分區名稱,此參數不允許使用函數等表達式,只能是常量。
  • select_statement:SELECT子句,從源表中查詢需要插入的數據。說明
    • 源表與目標表的對應關係依賴於在SELECT子句中列的順序,而不是表與表之間列名的對應關係。
    • 向某個分區插入數據時,分區列不允許出現在SELECT子句。
  • from_statement:FROM子句,代表數據來源。例如,源表名稱。

使用示例:

1. 計算sale_detail表中不同地區的銷售額存入表sale_detail_insert中:

-- 創建目標表sale_detail_insert
create table sale_detail_insert like sale_detail;

-- 給目標表增加分區
alter table sale_detail_insert add partition (
  sale_date='201912',
  region='guangzhou'
);

-- 從源表sale_detail中取出數據插入目標表sale_detail_insert
insert overwrite table sale_detail_insert
partition (sale_date='201912', region='guangzhou')
select shop_name, customer_id, total_price
from sale_detail where region='beijing';

-- 查詢插入的數據
select * from sale_detail_insert where region='guangzhou' and sale_date='201912';

查詢插入的結果如下:

shop_name	customer_id	total_price	sale_date	region
+----------+------------+------------+----------+-------+
unique	user1	1000.0	201912	guangzhou
adidas	user2	2000.0	201912	guangzhou
zara	user3	1500.0	201912	guangzhou
veromoda	user1	2000.0	201912	guangzhou
nike	user4	1000.0	201912	guangzhou
ur	user2	1400.0	201912	guangzhou
ochirly	user1	2000.0	201912	guangzhou
lily	user3	3000.0	201912	guangzhou
onemore	user2	1200.0	201912	guangzhou

2. 源表與目標表的對應關係依賴於在select子句中列的順序,而不是表與表之間列名的對應關係。例如如下語句:

insert overwrite table sale_detail_insert partition (sale_date='2018', region='china')
  select customer_id, shop_name, total_price from sale_detail;

此時,會將sale_detail.customer_id的數據插入sale_detail_insert.shop_name,將sale_detail.shop_name的數據插入sale_detail_insert.customer_id

3. 向某個分區插入數據時,分區列不允許出現在select列表中。下面語句報錯返回,sale_date,region爲分區列,不允許出現在靜態分區的insert語句中。

insert overwrite table sale_detail_insert partition (sale_date='2013', region='china')
   select shop_name, customer_id, total_price, sale_date, region  from sale_detail;

4. partition的值只能是常量,不可以出現表達式。以下爲錯誤用法。

insert overwrite table sale_detail_insert partition (sale_date=datepart('2016-09-18 01:10:00', 'yyyy') , region='china')
   select shop_name, customer_id, total_price from sale_detail;

使用動態分區注意事項

如果您需要更新表數據到動態分區,請注意以下事項:

  • insert into partition時,如果分區不存在,會自動創建分區。
  • 多個insert into partition作業併發時,如果分區不存在,會自動創建分區,但只會成功創建一個分區。

Insert多路輸出(MULTI INSERT)

MaxCompute SQL支持在一個語句中將數據插入不同的目標表或者分區中實現多路輸出。

命令格式

FROM from_statement
INSERT OVERWRITE | INTO TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)]
select_statement1 [FROM from_statement]
[INSERT OVERWRITE | INTO TABLE tablename2 [PARTITION (partcol1=val3, partcol2=val4 ...)]
select_statement2 [FROM from_statement]]
  • from_statement:FROM子句,代表數據來源。例如,源表名稱。
  • PARTITION (partcol1=val1, partcol2=val2 ...):需要插入數據的分區名稱,此參數不允許使用函數等表達式,只能是常量。
  • tablename1,tablename2:需要插入數據的目標表名稱。
  • select_statement:SELECT子句,從源表中查詢需要插入的數據。

使用示例:

1. 將表sale_detail的數據插入到sale_detail_multi裏的202003年及202004年中hangzhou和beijing的銷售記錄中:

-- 創建表sale_detail_multi
create table sale_detail_multi like sale_detail;

-- 開啓全表掃描,僅此session有效
set odps.sql.allow.fullscan=ture;

-- 將表sale_detail中的數據插入到表sale_detail_multi
from sale_detail
insert overwrite table sale_detail_multi partition (sale_date='202003', region='hangzhou')
select shop_name, customer_id, total_price where region='hangzhou'
insert overwrite table sale_detail_multi partition (sale_date='202004', region='beijing')
select shop_name, customer_id, total_price where region='beijing';

select * from sale_detail_multi;

查詢插入的數據如下:

shop_name	customer_id	total_price	sale_date	region
+----------+------------+------------+----------+-------+
unique	user1	1000.0	202003	hangzhou
adidas	user2	2000.0	202003	hangzhou
zara	user3	1500.0	202003	hangzhou
veromoda	user1	2000.0	202003	hangzhou
nike	user4	1000.0	202003	hangzhou
ur	user2	1400.0	202003	hangzhou
ochirly	user1	2000.0	202003	hangzhou
lily	user3	3000.0	202003	hangzhou
onemore	user2	1200.0	202003	hangzhou
unique	user1	1000.0	202004	beijing
adidas	user2	2000.0	202004	beijing
zara	user3	1500.0	202004	beijing
veromoda	user1	2000.0	202004	beijing
nike	user4	1000.0	202004	beijing
ur	user2	1400.0	202004	beijing
ochirly	user1	2000.0	202004	beijing
lily	user3	3000.0	202004	beijing
onemore	user2	1200.0	202004	beijing

 2. 如果同一分區出現多次,如下語句,則報錯返回:

from sale_detail
insert overwrite table sale_detail_multi partition (sale_date='2010', region='china' )
select shop_name, customer_id, total_price
insert overwrite table sale_detail_multi partition (sale_date='2010', region='china' )
select shop_name, customer_id, total_price;

3. 如果同一張表的不同分區,同時有insert overwrite和insert into操作,如下語句則報錯返回:

from sale_detail
insert overwrite table sale_detail_multi partition (sale_date='2010', region='china' )
select shop_name, customer_id, total_price
insert into table sale_detail_multi partition (sale_date='2011', region='china' )
select shop_name, customer_id, total_price;

輸出到動態分區(DYNAMIC PARTITION)

背景信息

在使用INSERT OVERWRITE語句將數據插入到分區表時,MaxCompute提供瞭如下兩種方式:

  • 輸出到靜態分區:在INSERT語句中直接指定分區值,將數據插入指定的分區。
  • 輸出到動態分區:在INSERT語句中不直接指定分區值,只指定分區列名。分區列的值在SELECT子句中提供,系統自動根據分區字段的值將數據插入到相應分區。

動態分區語法

INSERT OVERWRITE|INTO TABLE tablename PARTITION (partcol1, partcol2 ...) 
select_statement FROM from_statement;
  • tablename:需要插入數據的目標表表名。
  • partcol1, partcol2 ...:目標表分區列列名。
  • select_statement:源表的查詢語句。select_statement子句中的字段將提供目標表的動態分區值。如果目標表只有一級動態分區,則select_statement的最後一個字段值即爲目標表的動態分區值。源表SELECT的值和輸出分區的值的關係僅僅是通過位置來確定的,和字段名稱沒有關係。

使用示例:

示例1:將源表中的數據插入到目標表中。在SQL運行之前,無法得知會產生哪些分區。只有在語句運行結束後,才能通過region字段產生的值確定產生的分區。

-- 創建目標表total_revenues
create table total_revenues (revenue bigint) partitioned by (region string);

-- 將源表sale_detail中的數據插入到目標表total_revenues
-- MaxCompute 2.0 支持total_price的自動類型轉換,這裏MaxCompute 1.0不支持
insert overwrite table total_revenues partition (region)
select cast(total_price as bigint) as revenue, region from sale_detail where region='hangzhou';

select * from total_revenues;

插入數據查詢結果如下:

revenue	region
+--------+-------+
1000	hangzhou
2000	hangzhou
1500	hangzhou
2000	hangzhou
1000	hangzhou
1400	hangzhou
2000	hangzhou
3000	hangzhou
1200	hangzhou

示例2:將源表中的數據插入到目標表中。多級分區,指定一級分區sale_date。

insert overwrite table sale_detail_dypart partition (sale_date='2013', region)
select shop_name,customer_id,total_price,region from sale_detail;

示例3:動態分區插入時,動態分區列必須在SELECT列表中,否則會執行失敗,例如下面語句。

insert overwrite table sale_detail_dypart partition (sale_date='2013', region)
select shop_name,customer_id,total_price from sale_detail;

示例4:動態分區插入時,不能僅指定低級子分區,而動態插入高級分區,否則會執行失敗,例如下面語句。

insert overwrite table sales partition (region='china', sale_date)
select shop_name,customer_id,total_price,sale_date from sale_detail;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章