MaxCompute insert語句使用
本文介紹使用INSERT OVERWRITE和INSERT INTO兩種命令更新表數據,主要內容包括:
- insert into table ... values ...語句
- insert into/overwrite ... select ...語句
- Insert多路輸出(MULTI INSERT)
- 輸出到動態分區(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
,列爲a
、b
,類型分別爲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;