INSERT

功能概述

INSERT INTO
INSERT INTO
语句用于将数据插入表中。你可以为表中的每个列显式指定值,或者使用
SELECT
SELECT
查询的结果作为插入的数据源。

语法

INSERT INTO|OVERWRITE [TABLE] table_name [ PARTITION partition_spec] [ (column1, column2, ...)] {VALUES(value1 [,...],(value2 [,...]),...) | subquery} partition_spec ::= partition_column_name = partition_column_val [ , ... ]

参数说明

  1. INSERT INTO:追加写入,不影响表中已有数据——日常写入数据的标准方式。
  2. INSERT OVERWRITE:覆盖写入,清空目标表(或指定分区)后重新写入——适合每次全量刷新的场景,谨慎使用。
    • 对于分区表,将覆盖指定分区的数据。
    • 对于非分区表,将覆盖整个表的数据。
  3. TABLE:(可选)关键字,用于指定目标表。
  4. partition_spec:指定写入哪个分区——分区表必须提供分区值,非分区表不需要。
    • 静态分区:直接指定分区列的值,例如
      PARTITION (order_date='2024-01-01')
      PARTITION (order_date='2024-01-01')
    • 动态分区:系统根据
      VALUES
      VALUES
      SELECT
      SELECT
      语句的值自动映射到相应分区。
    • 如果未指定分区规范,系统将根据分区列的值自动选择分区。
  5. column_list:指定要插入数据的列,确保输入查询的列顺序与表中的列顺序相匹配。

使用指南

  • 数据类型匹配:确保插入的数据类型与表定义中的列类型相匹配。

  • 查询结果匹配:使用

    SELECT
    SELECT
    语句插入数据时,查询返回的列数量和顺序应与目标表的列相匹配。

  • 分区规范:在分区表中插入数据时,如果未指定分区规范,系统将根据分区列的值自动选择分区。确保插入的数据中包含有效的分区值。

  • INSERT OVERWRITE:使用此语句插入数据时,确保目标表或分区存在,否则操作将失败。

  • 数据检查:执行插入操作前,检查数据类型和列数量是否与目标表匹配,以避免数据插入错误。特别注意的是,Apache Hive要求分区列是最后一个位置。没有这种强制要求,因此加列的时候特别注意:按照原来Hive方式加列可能会将列加到最后一个位置,所以加列的时候必须指定位置。否则会造成数据错误。

  • 自动分区处理:当使用分区字段为函数的表时,无需指定

    PARTITION
    PARTITION
    子句,系统会自动根据函数返回值处理分区。

  • 大量数据导入:在lakehouse环境中,不推荐使用

    INSERT INTO...VALUES
    INSERT INTO...VALUES
    方式导入大量数据,这种方式更适合测试场景。对于大量数据导入,请参阅数据导入指南

使用示例

1. 基本 VALUES 插入

doc_test.products
doc_test.products
追加写入单行和多行数据。

-- 插入单行 INSERT INTO doc_test.products VALUES (101, 'Wireless Mouse', 89.90, 200, 'Electronics'); -- 插入多行(一次提交) INSERT INTO doc_test.products VALUES (102, 'USB-C Hub', 149.00, 150, 'Electronics'), (103, 'Desk Lamp', 59.50, 300, 'Office'); -- 验证 SELECT product_id, name, price, stock FROM doc_test.products WHERE product_id IN (101, 102, 103);

+------------+----------------+--------+-------+ | product_id | name | price | stock | +------------+----------------+--------+-------+ | 101 | Wireless Mouse | 89.90 | 200 | | 102 | USB-C Hub | 149.00 | 150 | | 103 | Desk Lamp | 59.50 | 300 | +------------+----------------+--------+-------+

2. 指定列名插入(省略部分列)

未指定的列填充 NULL(若列有默认值则使用默认值)。

-- 仅指定 product_id 和 name,其余列为 NULL INSERT INTO doc_test.products (product_id, name) VALUES (104, 'Notebook'); -- 验证 SELECT product_id, name, price, stock, category FROM doc_test.products WHERE product_id = 104;

+------------+----------+-------+-------+----------+ | product_id | name | price | stock | category | +------------+----------+-------+-------+----------+ | 104 | Notebook | NULL | NULL | NULL | +------------+----------+-------+-------+----------+

3. SELECT 插入(从查询结果写入另一张表)

将薪资高于 10000 的员工信息归档到备份表。

-- 创建归档表(与 employees 结构相同) CREATE TABLE IF NOT EXISTS doc_test.employees_archive LIKE doc_test.employees; -- 将薪资高于 10000 的员工写入归档表 INSERT INTO doc_test.employees_archive SELECT * FROM doc_test.employees WHERE salary > 10000; -- 验证:归档表中的行数 SELECT COUNT(*) AS archived_count FROM doc_test.employees_archive;

+----------------+ | archived_count | +----------------+ | 2 | +----------------+

salary > 10000
salary > 10000
的员工为 Alice(12000)和 Charlie(11000),共 2 行。

也可以只写入部分列:

INSERT INTO doc_test.employees_archive (id, name, dept) SELECT id, name, dept FROM doc_test.employees WHERE is_active = false;

4. 分区表插入数据

doc_test.orders
doc_test.orders
order_date
order_date
分区。插入时在 VALUES 末尾提供分区列的值,系统自动路由到对应分区。

-- 动态分区:系统根据 order_date 值自动选择分区 INSERT INTO doc_test.orders VALUES (5001, 1001, 'Wireless Mouse', 89.90, 'paid', '2024-03-01'), (5002, 1002, 'USB-C Hub', 149.00, 'pending', '2024-03-01'), (5003, 1003, 'Desk Lamp', 59.50, 'paid', '2024-03-02'); -- 静态分区:显式指定分区,VALUES 中无需再提供分区列 INSERT INTO doc_test.orders PARTITION (order_date='2024-03-03') (order_id, customer_id, product, amount, status) VALUES (5004, 1004, 'Notebook', 35.00, 'paid'); -- 验证 SELECT order_id, product, amount, order_date FROM doc_test.orders WHERE order_date IN ('2024-03-01','2024-03-02','2024-03-03');

+----------+----------------+--------+------------+ | order_id | product | amount | order_date | +----------+----------------+--------+------------+ | 5001 | Wireless Mouse | 89.90 | 2024-03-01 | | 5002 | USB-C Hub | 149.00 | 2024-03-01 | | 5003 | Desk Lamp | 59.50 | 2024-03-02 | | 5004 | Notebook | 35.00 | 2024-03-03 | +----------+----------------+--------+------------+

5. INSERT OVERWRITE(覆盖写入)

适合每日全量刷新场景——先清空目标分区,再写入当天最新数据。以下示例覆盖

2024-03-01
2024-03-01
分区(已有数据将被清除):

-- 覆盖单个分区 INSERT OVERWRITE doc_test.orders PARTITION (order_date='2024-03-01') (order_id, customer_id, product, amount, status) VALUES (5001, 1001, 'Wireless Mouse', 99.90, 'paid'), -- 金额已更新 (5005, 1005, 'Keyboard', 199.00, 'paid'); -- 新增订单,5002 行被清除 -- 验证:2024-03-01 分区只剩新写入的两行 SELECT order_id, product, amount FROM doc_test.orders WHERE order_date = '2024-03-01';

+----------+----------------+--------+ | order_id | product | amount | +----------+----------------+--------+ | 5001 | Wireless Mouse | 99.90 | | 5005 | Keyboard | 199.00 | +----------+----------------+--------+

对非分区表使用

INSERT OVERWRITE
INSERT OVERWRITE
会清空整张表后重新写入,适合维度表全量刷新:

-- 用最新数据集全量替换商品表 INSERT OVERWRITE doc_test.products SELECT * FROM doc_test.products_staging;

6. 插入不同的数据类型

展示各种内置类型的字面量写法,供类型映射参考。此示例仅演示语法,不展示查询输出。

CREATE TABLE doc_test.type_demo( `c_bigint` bigint, `c_boolean` boolean, `c_binary` binary, `c_char` char(1), `c_date` date, `c_decimal` decimal(20,6), `c_double` double, `c_float` float, `c_int` int, `c_smallint` smallint, `c_string` string, `c_timestamp` timestamp, `c_tinyint` tinyint, `c_array` array<int>, `c_map` map<string,string>, `c_struct` struct<a:int,b:string,c:double>, `c_varchar` varchar(100), `c_json` json); INSERT INTO doc_test.type_demo VALUES ( 1l, -- c_bigint true, -- c_boolean X'7A', -- c_binary 'A', -- c_char date'2025-05-21' , -- c_date 1.1bd, -- c_decimal 1.1d, -- c_double 1.1f, -- c_float 1, -- c_int 1s, -- c_smallint 'This is a string', -- c_string timestamp'2025-05-21 12:00:00', -- c_timestamp 127, -- c_tinyint ARRAY(1,2,3), -- c_array MAP('key1', 'value1', 'key2', 'value2'), -- c_map STRUCT(1, 'a', 3.14), -- c_struct 'This is a varchar string', -- c_varchar json'123' -- c_json );

相关指南

  • 批量插入数据:多种批量写入方式对比,含 INSERT INTO SELECT、VALUES 批量、COPY INTO 等场景
  • SQL DML使用指南:INSERT/UPDATE/DELETE/MERGE 的注意事项与最佳实践
联系我们
预约咨询
微信咨询
电话咨询