INSERT ... SELECT语句
INSERT [LOW_PRIORITY |HIGH_PRIORITY ] [IGNORE ] [INTO ] tbl_name [PARTITION (partition_name [, partition_name] ...)] [(col_name [, col_name] ...)] {SELECT ... |TABLE table_name} [ON DUPLICATE KEY UPDATE assignment_list] value: {expr |DEFAULT } assignment: col_name = value assignment_list: assignment [, assignment] ...
使用INSERT ... SELECT
,您可以从一个SELECT
语句的结果中快速将许多行插入到一个表中,该语句的结果可以从一个或多个表中进行选择。例如:
INSERT INTO tbl_temp2 (fld_id)SELECT tbl_temp1.fld_order_idFROM tbl_temp1WHERE tbl_temp1.fld_order_id > 100;
从MySQL 8.0.19开始,您可以使用TABLE
语句代替SELECT
,如下所示:
INSERT INTO taTABLE tb;
TABLE tb
等同于SELECT * FROM tb
。当将源表中的所有列插入目标表中并且不需要使用WHERE进行过滤时,此功能很有用。此外,from的行TABLE
可以使用来按一个或多个列排序ORDER BY
,并且可以使用LIMIT
子句限制插入的行数。有关更多信息,请参见“ TABLE语句”。
下列条件适用于INSERT ... SELECT
语句,除非另有说明,否则INSERT ... TABLE
也适用:
- 指定
IGNORE
忽略将导致重复键冲突的行。 INSERT
语句的目标表可以出现在查询部分的FROM
子句中,也可以显示SELECT
为命名的表TABLE
。但是,您不能插入表并在子查询中从同一表中选择。从同一表中选择并插入到同一表中时,MySQL创建一个内部临时表来保存来自的行
SELECT
,然后将这些行插入目标表中。但是,您不能使用INSERT INTO t ... SELECT ... FROM t
whent
是TEMPORARY
表,因为TEMPORARY
不能在同一条语句中两次引用表。出于同样的原因,您不能使用INSERT INTO t ... TABLE t
whent
是临时表。请参见“ MySQL中的内部临时表使用”和第B.4.6.2节“临时表问题”。AUTO_INCREMENT
列照常工作。- 为了确保二进制日志可用于重新创建原始表,MySQL不允许为
INSERT ... SELECT
或INSERT ... TABLE
语句进行并发插入(请参见“并发插入”)。 为避免当
SELECT
和INSERT
引用同一表时出现列引用不明确的问题,请为SELECT
零件中使用的每个表提供唯一的别名,并使用适当的别名限定该零件中的列名。该
TABLE
语句不支持别名。
您可以显式选择要使用源表或目标表(或两者)的分区或子分区(或两者),并PARTITION
在表名后面使用一个选项。当在语句PARTITION
的SELECT
一部分中与源表的名称一起使用时,仅从其分区列表中命名的分区或子分区中选择行。当PARTITION
与INSERT
语句的目标表的名称一起使用时,必须可以将所有选择的行插入到该选项后面的分区列表中命名的分区或子分区中。否则,该INSERT ... SELECT
语句将失败。有关更多信息和示例,请参见“分区选择”。
TABLE
不支持PARTITION
选项。
对于INSERT ... SELECT
语句,请参见“在重复键更新语句上插入...”,SELECT
以了解在ON DUPLICATE KEY UPDATE
子句中可以引用列的条件。这也适用于INSERT ... TABLE
。
不带子句的SELECT
or TABLE
语句ORDER BY
返回行的顺序是不确定的。这意味着,在使用复制时,不能保证这样的SELECT
返回在主服务器和从服务器上以相同的顺序返回行,这可能导致它们之间的不一致。为了防止这种情况发生,总是写INSERT ... SELECT
或INSERT ... TABLE
于使用复制陈述,ORDER BY
产生对主单元和从属同一行顺序子句。另请参见“复制功能”。
由于此问题,对于基于语句的复制INSERT ... SELECT ON DUPLICATE KEY UPDATE
,INSERT IGNORE ... SELECT
语句被标记为不安全。当使用基于语句的模式时,此类语句在错误日志中产生警告,并在使用MIXED
模式时使用基于行的格式写入二进制日志。(缺陷#11758262,缺陷#50439)
另请参见“复制格式”。