Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 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 ... 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 子句进行过滤时,插入源表中的所有列到目标表中。此外,来自TABLE的行可以使用 ORDER BY 子句对其进行排序,并且可以使用 LIMIT 子句来限制插入的行数。更多信息,请见第15.2.16节,“TABLE 语句”

以下条件适用于INSERT ... SELECT语句,以及,除非特别注明外,对于INSERT ... TABLE也适用:

  • 指定 IGNORE 忽略将导致重复键违规的行。

  • INSERT 语句的目标表可能出现在查询中的 FROM 子句中,或者作为由 TABLE 指定的表名。然而,您不能在子查询中插入到一个表并从同一个表中选择数据。

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

  • AUTO_INCREMENT 列工作正常。

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

  • 为了避免在SELECT和INSERT语句中出现ambiguous column reference问题,当SELECT和INSERT语句引用同一表时,提供每个表在SELECT部分的唯一别名,并在该部分使用适当别名来限定列名。

    TABLE语句不支持别名。

您可以使用 PARTITION 子句,明确选择源或目标表(或两者)的某些分区或子分区。对于在 SELECT 语句中使用 PARTITION 的源表名,仅选择来自于其分区列表中的分区或子分区。对于在 INSERT 语句中使用 PARTITION 的目标表名,必须能够将所有选择的行插入到分区列表中的分区或子分区中。否则,INSERT ... SELECT 语句失败。更多信息和示例,请见 第26.5节,“分区选择”

TABLE 不支持 PARTITION 子句。

对于 INSERT ... SELECT 语句,请见 第15.2.7.2节,“INSERT ... ON DUPLICATE KEY UPDATE Statement”,了解在何种情况下可以在 ON DUPLICATE KEY UPDATE 子句中引用 SELECT 列。同样适用于 INSERT ... TABLE

没有使用ORDER BY子句的SELECTTABLE语句的执行顺序是非确定性的。这意味着,在使用复制时,没有保证在源服务器和副本服务器上该语句返回行的相同顺序,这可能会导致它们之间的不一致。为了防止这种情况发生,总是使用ORDER BY子句来生产源服务器和副本服务器上的行顺序相同的INSERT ... SELECTINSERT ... TABLE语句。请参见第19.5.1.18节,“复制和LIMIT”.

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

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