MySQLに_table1
_と_table2
_があります。どちらにも基本的な_auto_increment
_キーid
があります。
テーブルスキーマが一致し、私がINSERT INTO table1 (SELECT * FROM table2)
を実行すると、_table1
_に挿入された新しい行に関して何が起こりますか? _table1
_の行に同じid
がある場合、古いid
値を保持し、競合を生成しますか? auto_incrementによって新しい値が生成されますか?ストレージエンジンまたはロックに依存しますか?
自動インクリメント列に挿入して値を指定できます。これは問題ありません。自動インクリメントジェネレーターをオーバーライドするだけです。
NULLまたは0またはDEFAULT
の値を挿入しようとした場合、またはINSERTステートメントの列から自動インクリメント列を省略した場合、これにより自動インクリメントジェネレーターがアクティブになります。
したがって、INSERT INTO table1 SELECT * FROM table2
で問題ありません(ちなみに、括弧は必要ありません)。つまり、table2
のid値はそのままコピーされ、table1
はnotで新しい値を生成します。
wanttable1
を使用して新しい値を生成する場合、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 * for one column」以外の構文はありません。挿入する列名の完全なリストを入力する必要があります。
選択からのIDは、テーブルに挿入されたものと同じ値になります。既存の行を複製しようとすると、エラーになります。
Bill Karwin:質問する前に、SQLには「select * for one column」以外の構文はありません。
これはいくつかの創造性で達成できます:
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が新しい行に取得されます。