INSERT 语句

最近更新时间:2026-05-06 16:28:13

我的收藏
INSERT 语句用于向 TCHouse-X 的内表或外表中添加、追加或替换数据。

语法

[WITH with_clause]
INSERT { INTO | OVERWRITE } [TABLE] table_name
[(column_list)]
[ PARTITION (partition_clause)]
{
select_statement
| VALUES (value [, value ...]) [, (value [, value ...]) ...]
}

partition_clause ::= col_name [= constant] [, col_name [= constant] ...]
核心子句说明:
INTO:将数据追加到表中,保留现有数据。
OVERWRITE:替换表中的现有数据。旧数据文件会被立即物理删除。
column_list(列排列):可选。指定插入的目标列子集及其顺序。未提及的列将自动填充为 NULL。

使用限制与特性

不同表类型(内表 vs 外表)在执行 INSERT 时有显著差异:

内表 (Internal Table)

不支持的操作:不支持 OVERWRITE 语法,不支持 PARTITION 子句。
可见性延迟:插入数据后不会立即生效。若需立即可见,需执行:ALTER TABLE table_name EXECUTE SYNC_DATA();
主键去重:若插入的主键值已存在,新数据将覆盖旧数据。
注意:由于分布式查询结果顺序的不确定性,对主键表使用 INSERT SELECT 可能导致结果不唯一。

外表 (External Table)

环境设置:必须关闭向量化引擎:SET ENABLE_VECTORIZED_EXECUTOR = false;
支持情况:支持 OVERWRITE 填充和 PARTITION 分区插入。
格式支持:目前仅支持写入 TEXTPARQUET 格式。不支持 RCFileSequenceFile

分区插入 (仅限外表)

静态分区插入

PARTITION 子句中明确指定分区键的常量值。
-- 关闭向量化引擎
SET ENABLE_VECTORIZED_EXECUTOR = false;

-- 此时 SELECT 只需要提供非分区列的值
INSERT INTO t_partitioned PARTITION (year=2024, month=1)
SELECT id, name FROM source_table;

动态分区插入

分区键在 PARTITION 子句中列举但不赋值,由 SELECTVALUES 结果集的最后几列动态填充。
-- 关闭向量化引擎
SET ENABLE_VECTORIZED_EXECUTOR = false;

-- 分区键 x, y 的值将取自 VALUES 结果集的最后两个位置
INSERT INTO t1 PARTITION (x, y) VALUES (1, 2, 'c');
-- 等价于:w=1, x=2, y='c'

关键注意事项

数据类型匹配:系统不会自动将大类型转换为小类型。例如,将 DOUBLE 函数结果存入 FLOAT 列时,必须手动执行 CAST()INSERT INTO t1 SELECT CAST(COS(angle) AS FLOAT) ...
VALUES 性能INSERT ... VALUES 每次操作都会生成一个小文件且无法并行,严禁用于大规模 ETL 导入。该语法仅适用于小型维度表或语法测试。
排序忽略INSERT ... SELECT 中的 ORDER BY 子句会被优化器忽略,因为并行写入无法保证全局有序性。

示例

主键内表的数据覆盖

CREATE TABLE pk_table (id INT PRIMARY KEY, val STRING);
INSERT INTO pk_table VALUES (1, 'old');

-- 插入相同主键
INSERT INTO pk_table VALUES (1, 'new');
ALTER TABLE pk_table EXECUTE SYNC_DATA();

-- 结果 id=1 的值为 'new'
SELECT * FROM pk_table;

外表的分区列排列操作

-- 列排列:只插入 c1, c2 两列,跳过 c3
INSERT INTO target_table (c1, c2) SELECT x, y FROM source_table;

-- 动态分区:w取1, x取2, y取'c'
INSERT INTO t_ext_partitioned (w) PARTITION (x, y) VALUES (1, 2, 'c');