本文向您介绍如何使用INSERT OVERWRITE和INSERT INTO两种命令更新表数据。

INSERT命令说明

命令格式
INSERT OVERWRITE|INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)] [(col1,col2 ...)]
select_statement
FROM from_statement;

功能说明

在MaxCompute SQL处理数据的过程中,INSERT OVERWRITE/INTO用于将计算的结果保存目标表中。
  • insert into:直接向表或表的分区中追加数据。不支持INSERT INTO到Hash Clustering表。如果您需要插入少量测试数据,可以配合VALUES使用。
  • insert overwrite:先清空表中的原有数据,再向表或分区中插入数据。目前INSERT OVERWRITE不支持指定插入列的功能,暂时只能用INSERT INTO
    说明
    • MaxCompute的INSERT语法与通常使用的MySQL或Oracle的INSERT语法有差别,在INSERT OVERWRITE/INTO后需要加入TABLE关键字,而非直接使用TABLENAME
    • 在反复对同一个分区进行INSERT OVERWRITE的时候,通过DESCRIBE查看到的数据分区Size会不同。这是因为从同一个表的同一个分区SELECT出来再INSERT OVERWRITE回相同分区时,文件切分逻辑发生变化,从而导致数据的Size发生变化。数据的总长度在INSERT OVERWRITE前后是不变的,您不必担心存储计费会存在问题。
    • 当遇到并发写入时,MaxCompute会根据ACID进行并发写的保障。关于ACID的具体语义,请参见ACID语义
参数说明
  • tablename:需要插入数据的目标表名称。
  • PARTITION (partcol1=val1, partcol2=val2 ...):需要插入数据的分区名称,此参数不允许使用函数等表达式,只能是常量。
  • select_statement:SELECT子句,从源表中查询需要插入的数据。
    说明
    • 源表与目标表的对应关系依赖于在SELECT子句中列的顺序,而不是表与表之间列名的对应关系。
    • 向某个分区插入数据时,分区列不允许出现在SELECT子句。
  • from_statement:FROM子句,代表数据来源。例如,源表名称。
示例
  • 计算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='2013', region='china');
    
    --从源表sale_detail中取出数据插入目标表sale_detail_insert。
    insert overwrite table sale_detail_insert partition (sale_date='2013', region='china')
      select shop_name, customer_id,total_price from sale_detail;
  • 源表与目标表的对应关系依赖于在select子句中列的顺序,而不是表与表之间列名的对应关系。例如如下语句。
    insert overwrite table sale_detail_insert partition (sale_date='2013', region='china')
        select customer_id, shop_name, total_price from sale_detail;                      

    在创建sale_detail_insert表时,列的顺序为shop_name string、customer_id string、total_price bigint,而从sale_detailsale_detail_insert插入数据的顺序为customer_id、shop_name、total_price。此时,会将sale_detail.customer_id的数据插入sale_detail_insert.shop_name,将sale_detail.shop_name的数据插入sale_detail_insert.customer_id

  • 向某个分区插入数据时,分区列不允许出现在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;
  • 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 into partition作业并发,则只能通过预创建分区避免问题。
更多动态分区详情请参考输出到动态分区(DYNAMIC PARTITION)