• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 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_id
      FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100;
    

    从MySQL 8.0.19开始,您可以使用TABLE语句代替SELECT,如下所示:

    INSERT INTO ta TABLE 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 twhen tTEMPORARY表,因为TEMPORARY不能在同一条语句中两次引用表。出于同样的原因,您不能使用INSERT INTO t ... TABLE twhen t是临时表。请参见“ MySQL中的内部临时表使用”和第B.4.6.2节“临时表问题”。

    • AUTO_INCREMENT列照常工作。
    • 为了确保二进制日志可用于重新创建原始表,MySQL不允许为INSERT ... SELECTINSERT ... TABLE语句进行并发插入(请参见“并发插入”)。
    • 为避免当SELECTINSERT引用同一表时出现列引用不明确的问题,请为SELECT零件中使用的每个表提供唯一的别名,并使用适当的别名限定该零件中的列名。

      TABLE语句不支持别名。

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

    TABLE不支持PARTITION选项。

    对于INSERT ... SELECT语句,请参见“在重复键更新语句上插入...”,SELECT以了解在ON DUPLICATE KEY UPDATE子句中可以引用列的条件。这也适用于INSERT ... TABLE

    不带子句的SELECTor TABLE语句ORDER BY返回行的顺序是不确定的。这意味着,在使用复制时,不能保证这样的SELECT返回在主服务器和从服务器上以相同的顺序返回行,这可能导致它们之间的不一致。为了防止这种情况发生,总是写INSERT ... SELECTINSERT ... TABLE于使用复制陈述,ORDER BY产生对主单元和从属同一行顺序子句。另请参见“复制功能”。

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

    另请参见“复制格式”。