Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

MySQL 8.3 Reference Manual  /  ...  /  INSERT ... SELECT Statement

15.2.7.1 插入 ... 选择语句

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 INTO tbl_temp2 (fld_id)
  SELECT tbl_temp1.fld_order_id
  FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100;

语句可以代替 选择,如下所示:

INSERT INTO ta TABLE tb;

表 tb 等同于 选择 * FROM tb。它在插入源表的所有列到目标表时非常有用,并且不需要使用 WHERE 进行过滤。此外,来自 的行可以使用 ORDER BY 按一个或多个列排序,并且可以使用 LIMIT 子句限制插入的行数。有关更多信息,请参阅 第 15.2.16 节,“表语句”

以下条件适用于 插入 ... 选择 语句,并且(除非另有说明)也适用于 插入 ... 表 语句:

  • 指定 忽略 以忽略可能导致重复键违规的行。

  • 目标表可能出现在 插入 语句的 FROM 子句中,或者作为 语句命名的表。然而,您不能在同一个语句中插入到表中并从同一个表中选择。

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

  • AUTO_INCREMENT 列按通常方式工作。

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

  • 为了避免ambiguous 列引用问题,当 选择插入 都引用同一个表时,请为 选择 部分中的每个表提供唯一的别名,并使用该别名限定该部分中的列名。

    语句不支持别名。

您可以使用 PARTITION 子句明确选择源表或目标表(或两者)的哪些分区或子分区将被使用。当 PARTITION 用于 SELECT 语句的源表名称时,只有在其分区列表中命名的分区或子分区中的行将被选择。当 PARTITION 用于目标表的 INSERT 部分时,必须能够将所有选定的行插入到分区列表中命名的分区或子分区中。否则,INSERT ... SELECT 语句将失败。有关更多信息和示例,请参阅 第 26.5 节,“分区选择”

TABLE 不支持 PARTITION 子句。

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

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

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

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