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 以降、次に示すように、SELECT
のかわりに TABLE
ステートメントを使用できます:
INSERT INTO ta TABLE tb;
TABLE tb
は、SELECT * FROM tb
と同等です。 これは、ソーステーブルのすべてのカラムをターゲットテーブルに挿入し、WHERE によるフィルタリングが不要な場合に便利です。 また、TABLE
の行は ORDER BY
を使用して 1 つ以上のカラムで順序付けでき、挿入される行数は LIMIT
句を使用して制限できます。 詳細は、セクション13.2.12「TABLE ステートメント」を参照してください。
次の条件は、INSERT ... SELECT
ステートメント、および特に明記されている場合を除き、INSERT ... TABLE
にも適用されます:
重複キー違反の原因になる行を無視するには、
IGNORE
を指定します。-
INSERT
ステートメントのターゲットテーブルは、クエリーのSELECT
部分のFROM
句に、またはTABLE
によって指定されたテーブルとして指定できます。 ただし、テーブルに挿入し、さらにサブクエリーで同じテーブルから選択することはできません。同じテーブルから選択して同じテーブルに挿入する場合、MySQL は、
SELECT
の行を保持する内部一時テーブルを作成し、それらの行をターゲットテーブルに挿入します。 ただし、同じステートメントでTEMPORARY
テーブルを 2 回参照することはできないため、t
がTEMPORARY
テーブルの場合はINSERT INTO t ... SELECT ... FROM t
を使用できません。 同じ理由で、t
が一時テーブルの場合はINSERT INTO t ... TABLE t
を使用できません。 セクション8.4.4「MySQL での内部一時テーブルの使用」およびセクションB.3.6.2「TEMPORARY テーブルに関する問題」を参照してください。 AUTO_INCREMENT
カラムは、通常どおりに機能します。バイナリログを使用して元のテーブルを再作成できるようにするために、MySQL では
INSERT ... SELECT
またはINSERT ... TABLE
ステートメントの同時挿入が許可されていません (セクション8.11.3「同時挿入」 を参照)。-
SELECT
とINSERT
が同じテーブルを参照している場合のあいまいなカラム参照の問題を回避するには、SELECT
部分で使用されている各テーブルの一意のエイリアスを指定し、その部分にあるカラム名を適切なエイリアスで修飾します。TABLE
ステートメントはエイリアスをサポートしていません。
ソーステーブルまたはターゲットテーブル (あるいはその両方) のどのパーティションまたはサブパーティション (あるいはその両方) を、テーブルの名前に続く PARTITION
オプションとともに使用するかを明示的に選択できます。 PARTITION
がこのステートメントの SELECT
部分にあるソーステーブルの名前とともに使用されている場合は、そのパーティションリストで指定されているパーティションまたはサブパーティションの行のみが選択されます。 PARTITION
をステートメントの INSERT
部分のターゲットテーブルの名前とともに使用する場合、選択したすべての行を、オプションの後のパーティションリストで指定されたパーティションまたはサブパーティションに挿入できる必要があります。 それ以外の場合、INSERT ... SELECT
ステートメントは失敗します。 詳細および例については、セクション24.5「パーティション選択」を参照してください。
TABLE
は、PARTITION
オプションをサポートしていません。
INSERT ... SELECT
ステートメントの場合、ON DUPLICATE KEY UPDATE
句で SELECT
カラムを参照できる条件については、セクション13.2.6.2「INSERT ... ON DUPLICATE KEY UPDATE ステートメント」 を参照してください。 これは、INSERT ... TABLE
でも機能します。
ORDER BY
句のない SELECT
ステートメントまたは TABLE
ステートメントが行を戻す順序は、非決定的です。 つまり、レプリケーションを使用している場合、このような SELECT
がソースとスレーブで同じ順序で行を返すことは保証されないため、それらの間に不整合が生じる可能性があります。 これが発生しないようにするには、ソースとレプリカで同じ行順序を生成する ORDER BY
句を使用して、レプリケートされる INSERT ... SELECT
ステートメントまたは INSERT ... TABLE
ステートメントを常に記述します。 セクション17.5.1.18「レプリケーションと LIMIT」も参照してください。
この問題のため、INSERT ... SELECT ON DUPLICATE KEY UPDATE
および INSERT IGNORE ... SELECT
ステートメントには、ステートメントベースレプリケーションに対して安全でないというフラグが付けられます。 このようなステートメントは、ステートメントベースのモードの使用時にエラーログに警告を生成し、MIXED
モードの使用時に行ベースの形式を使用してバイナリログに書き込まれます。 (Bug #11758262、Bug #50439)
セクション17.2.1.1「ステートメントベースおよび行ベースレプリケーションのメリットとデメリット」も参照してください。