文档主页
MySQL 9.0 参考手册
相关文档 下载本手册
PDF (US Ltr) - 40.0Mb
PDF (A4) - 40.1Mb
手册页 (TGZ) - 258.2Kb
手册页 (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 9.0 参考手册  /  ...  /  INSERT ... SELECT 语句

15.2.7.1 INSERT ... SELECT 语句

INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    [(col_name [, col_name] ...)]
    {   SELECT ... 
      | TABLE table_name 
      | VALUES row_constructor_list
    }
    [ON DUPLICATE KEY UPDATE assignment_list]


value:
    {expr | DEFAULT}

value_list:
    value [, value] ...

row_constructor_list:
    ROW(value_list)[, ROW(value_list)][, ...]

assignment:
    col_name = 
          value
        | [row_alias.]col_name
        | [tbl_name.]col_name
        | [row_alias.]col_alias

assignment_list:
    assignment [, assignment] ...

使用 INSERT ... SELECT,您可以快速地将 SELECT 语句(该语句可以从一个或多个表中选择)的结果插入到表中,例如

INSERT INTO tbl_temp2 (fld_id)
  SELECT tbl_temp1.fld_order_id
  FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100;

TABLE 语句代替 SELECT,如下所示

INSERT INTO ta TABLE tb;

TABLE tb 等同于 SELECT * FROM tb。当将源表中的所有列插入到目标表中,并且不需要使用 WHERE 进行筛选时,这非常有用。此外,可以使用 ORDER BYTABLE 中的行的顺序进行排序,并可以使用 LIMIT 子句限制插入的行数。有关更多信息,请参阅 第 15.2.16 节“TABLE 语句”.

以下条件适用于 INSERT ... SELECT 语句,并且除了特别说明外,还适用于 INSERT ... TABLE

  • 指定 IGNORE 以忽略会导致重复键冲突的行。

  • INSERT 语句中,目标表可能出现在 SELECT 部分查询的 FROM 子句中,或者作为由 TABLE 命名的表。但是,您不能在子查询中将数据插入一个表并从同一个表中选择数据。

    当从同一个表中选择数据并插入数据时,MySQL 会创建一个内部临时表来保存来自 SELECT 的行,然后将这些行插入目标表。但是,当 t 是一个 TEMPORARY 表时,您不能使用 INSERT INTO t ... SELECT ... FROM t,因为 TEMPORARY 表不能在同一个语句中被引用两次。出于同样的原因,当 t 是一个临时表时,您不能使用 INSERT INTO t ... TABLE t。请参阅 第 10.4.4 节,“MySQL 中内部临时表的使用”第 B.3.6.2 节,“TEMPORARY 表问题”

  • AUTO_INCREMENT 列按预期工作。

  • 为了确保可以使用二进制日志来重新创建原始表,MySQL 不允许对 INSERT ... SELECTINSERT ... TABLE 语句进行并发插入(请参阅 第 10.11.3 节,“并发插入”)。

  • 为了避免在 SELECTINSERT 引用同一个表时出现不明确的列引用问题,请为 SELECT 部分中使用的每个表提供唯一的别名,并在该部分中使用相应的别名限定列名。

    TABLE 语句不支持别名。

您可以使用在表名后跟随的 PARTITION 子句显式选择要使用的源表或目标表(或两者)的哪些分区或子分区(或两者)。当 PARTITIONSELECT 部分语句中的源表名称一起使用时,仅从其分区列表中命名的分区或子分区中选择行。当 PARTITIONINSERT 部分语句的目标表名称一起使用时,必须能够将所有选定的行插入选项后面的分区列表中命名的分区或子分区中。否则,INSERT ... SELECT 语句将失败。有关更多信息和示例,请参阅 第 26.5 节,“分区选择”

TABLE 不支持 PARTITION 子句。

对于 INSERT ... SELECT 语句,请参阅 第 15.2.7.2 节,“INSERT ... ON DUPLICATE KEY UPDATE 语句”,了解 SELECT 列可以在 ON DUPLICATE KEY UPDATE 子句中引用的条件。这也适用于 INSERT ... TABLE

不带 ORDER BY 子句的 SELECTTABLE 语句返回行的顺序是不确定的。这意味着,当使用复制时,不能保证这样的 SELECT 在源和副本上按相同的顺序返回行,这可能导致它们之间出现不一致。为了防止这种情况发生,始终使用 ORDER BY 子句编写要复制的 INSERT ... SELECTINSERT ... TABLE 语句,该子句在源和副本上产生相同的行顺序。另请参阅 第 19.5.1.19 节,“复制和 LIMIT”

由于这个问题,INSERT ... SELECT ON DUPLICATE KEY UPDATEINSERT IGNORE ... SELECT 语句被标记为对基于语句的复制不安全。此类语句在使用基于语句的模式时会在错误日志中生成警告,并且在使用 MIXED 模式时以基于行的格式写入二进制日志。(Bug #11758262,Bug #50439)

另请参阅 第 19.2.1.1 节,“基于语句的复制和基于行的复制的优缺点”