如何在INSERT中处理auto_increment键(SELECT * FROM…)


13

table1table2MySQL中。两者都有一个主auto_incrementid

如果表模式匹配,并且INSERT INTO table1 (SELECT * FROM table2)对插入到其中的新行该table1怎么办?难道他们保留他们原来的id价值和产生冲突时,从行table1具有相同的id?auto_increment是否生成新值?它取决于存储引擎还是锁定?

Answers:


13

您可以插入自动增量列中并指定一个值。这可以; 它只是覆盖了自动增量生成器。

如果您尝试插入NULL或0或值DEFAULT,或者如果您从INSERT语句的列中省略了auto-increment列,则这将激活auto-increment生成器。

因此,这样做很好INSERT INTO table1 SELECT * FROM table2(顺便说一下,您不需要括号)。这意味着,在ID值table2将被逐字复制,并且table1不会产生新的价值。

如果 table1生成新值,则不能这样做SELECT *。您为id列使用null或0:

INSERT INTO table1 SELECT 0, col1, col2, col3, ... FROM table2;

否则,您将从INSERT语句的列列表和SELECT语句的选择列表中都忽略该列:

-- No id in either case:
INSERT INTO table1 (col1, col2, col3) SELECT col1, col2, col3, ... FROM table2;

在询问之前,SQL中没有“ select *除了一列”的语法。您必须拼出要插入的列名的完整列表。


是否没有允许/禁止插入0作为值的选项?(关于您的第二段)
Sascha Rambeaud 2014年

1
是的,SQL_MODE = NO_AUTO_VALUE_ON_ZERO,否则我们永远不能在AI列中插入文字零值。如果使用此SQL模式,则NULL仍然可以激活AI生成器,或者省略该列也可以。
比尔·卡温

@BillKarwin,关于您的最后一段,在获得子结果之后select * from table,是否有办法对该子结果进行操作以删除其第一列?
Pacerier

@Pacerier,如果我理解正确,您在问是否select *可以表示select * except for the first column。答案是不。select *始终请求该表中的所有列。如果需要子集,则必须拼出所需的列。
比尔·卡温

@BillKarwin,嗯,我正在考虑将表旋转为垂直的where子句,然后将其向后旋转,例如,select*from transpose(select*from(transpose(select*from table where Id=1))where col_name<>Id)或更简洁地说select*from table where Id=1 and $col<>Id,您怎么看?
Pacerier

3

选择的ID将与插入表中的ID相同。如果您要复制现有行,将导致错误。

Bill Karwin:在您询问之前,SQL中没有“ select *除了一列”的语法。

这可以通过一些创造力来实现:

SET @sql = CONCAT('INSERT INTO <table> SELECT null, 
    ', (SELECT GROUP_CONCAT(COLUMN_NAME) 
    FROM information_schema.columns 
    WHERE table_schema = '<database>' 
    AND table_name = '<table>' 
    AND column_name NOT IN ('id')), ' 
from <table> WHERE id = <id>');  

PREPARE stmt1 FROM @sql;
EXECUTE stmt1;

这将导致新行获得一个自动递增的ID,而不是所选行中的ID。


2
聪明,但对我而言,这相当于您要插入的列名的完整列表。
比尔·卡温

1
好吧,这是mysql自动将其拼写出来,而不是手动执行。如果您的表具有很多列,则可以防止遗漏一列或拼写错误。
2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.