Skip to content

SQL Insert Into Select

SQL INSERT INTO SELECT:在表之间复制数据

Section titled “SQL INSERT INTO SELECT:在表之间复制数据”

使用 SQL 高效复制数据

SQL 提供了一种强大而高效的方法,可以使用 INSERT INTO SELECT 语句将数据从一个表复制并插入到另一个现有表中。这对于各种数据管理任务都非常有用。

INSERT INTO SELECT 语句允许你从源表(或使用连接从多个表)查询数据,并将结果直接插入到目标表中。重要的是,目标表中任何现有行不受影响;新行只是被追加。

使用此语句主要有两种方式:

  1. 复制所有列(要求结构匹配):

INSERT INTO target_table SELECT * FROM source_table WHERE condition; — 可选:用于选择特定行

使用 SELECT * 时,source_table 必须与 target_table 具有相同数量的列,并且对应列的数据类型必须兼容。列的顺序是隐式匹配的。

  1. 复制特定列(更灵活,推荐使用):

INSERT INTO target_table (column1_target, column2_target, …) SELECT column1_source, column2_source, … FROM source_table WHERE condition; — 可选:用于选择特定行

这种方法通常更安全、更明确,因为你指定了哪些源列映射到哪些目标列。数据类型仍然必须兼容。

让我们考虑一个简化的场景,使用 Customers 表和 Suppliers 表,灵感来源于 Northwind 数据库模式。

Customers 表结构示例:

CustomerIDCustomerNameContactNameAddressCityPostalCodeCountry
1Alfreds FutterkisteMaria AndersObere Str. 57Berlin12209Germany
… more customers …

Suppliers 表结构示例:

SupplierIDSupplierNameContactNameAddressCityPostalCodeCountryPhone
1Exotic LiquidsCharlotte Cooper49 Gilbert St.LondonEC1 4SDUK(171) 555-2222
… more suppliers …

示例 1:将特定的供应商详情复制到 Customers 表中。

假设我们想将供应商作为潜在客户添加,复制他们的名称和国家。

INSERT INTO Customers (CustomerName, City, Country)
SELECT SupplierName, City, Country
FROM Suppliers;

此查询从 Suppliers 表的所有行中选择 SupplierName、City 和 Country,并将它们插入到 Customers 表中对应的 CustomerName、City 和 Country 列中。如果 CustomerID 是自增主键,通常会自动生成新的 CustomerID;如果不是,则需要进行处理。

示例 2:仅将德国的供应商复制到 Customers 表中。

我们可以在 SELECT 部分使用 WHERE 子句来过滤要复制的数据。

INSERT INTO Customers (CustomerName, City, Country, ContactName)
SELECT SupplierName, City, Country, ContactName
FROM Suppliers
WHERE Country = 'Germany';

这只会将位于“Germany”的供应商复制到 Customers 表中。

  • 数据类型兼容性:确保 SELECT 语句中列的数据类型与 target_table 中列的数据类型兼容。不匹配可能导致错误或数据截断。
  • 列顺序:未指定目标列时(即,INSERT INTO target_table SELECT ...),所选列的数量和顺序必须与 target_table 的结构匹配。最佳实践是始终指定目标列,以提高清晰度,并避免在表结构更改时出现问题。
  • 约束:要插入的数据必须符合 target_table 上的所有约束,例如 NOT NULL、UNIQUE、CHECK 和 FOREIGN KEY 约束。违反约束将导致 INSERT 操作失败。
  • 性能:对于非常大的数据集,INSERT INTO SELECT 通常是高效的。但是,请确保 SELECT 查询本身已优化。在进行大规模插入时禁用目标表上的索引并在之后重建它们,有时可以加快过程,但这是一种高级技术。
  • 事务:对于关键操作,将 INSERT INTO SELECT 语句封装在事务中,以确保数据一致性。如果发生错误,你可以回滚更改。
  • 数据归档:将旧的或不活跃的记录从活跃表移动到归档表。
  • 填充测试环境:将生产数据库中的数据(或其子集)复制到开发或测试数据库。
  • 数据聚合/汇总:通过从一个或多个详细表中选择和转换数据来创建汇总表。
  • 数据迁移:在模式重新设计或系统升级期间在表之间传输数据。