🦔

MySQL8.0で別テーブルでSELECTした結果をINSERTする

2022/01/22に公開

背景

MySQL8.0でHAVING句を理解するに引き続いて応用情報の勉強中です.

今回は別テーブルでSELECTした結果をINSERTするやり方についてです.何度か使ったことはあるし,こんなの間違えねぇよ〜と思っていたんですが,何も見ずにSQLを書いてみると間違ってしまったのでメモを残しておきます.
MySQLの環境は前記事と同様にこちらを使いました.

準備

create database insert_select_app
use insert_select_app
create table article_to (
    id int not null primary key AUTO_INCREMENT,
    title varchar(40) not null,
    text varchar(200) not null
);

create table article_from (
    id int not null primary key AUTO_INCREMENT,
    title varchar(40) not null,
    text varchar(200) not null
);
insert into article_from (title, text) values 
('abc', 'test_text1'),
('xyz', 'test_text2'),
('hogehoge', 'test_text3');

select * from article_from;
+----+----------+------------+
| id | title    | text       |
+----+----------+------------+
|  1 | abc      | test_text1 |
|  2 | xyz      | test_text2 |
|  3 | hogehoge | test_text3 |
+----+----------+------------+

別テーブルでSELECTした結果をINSERT

article_fromテーブルには3レコード入っており,それをarticle_toテーブルに登録していきます.

insert article_to
select *
from article_from;
select * from article_to;
+----+----------+------------+
| id | title    | text       |
+----+----------+------------+
|  1 | abc      | test_text1 |
|  2 | xyz      | test_text2 |
|  3 | hogehoge | test_text3 |
+----+----------+------------+

article_fromテーブルをselectして,その結果をarticle_toテーブルに登録できました.select句がカッコなしで途中に入る構文ってあまり見ない気がします.
insert句にvalues句は不要です.

再度同じinsert文を実行してみるとエラーになります.idが主キーでその制約に引っかかってしまいました.

insert article_to
select *
from article_from;
ERROR 1062 (23000): Duplicate entry '1' for key 'article_to.PRIMARY'

再度同じデータを登録したい場合は,article_fromテーブルのid以外の結果を登録すれば良いので以下のように列を指定します.
select句はselect article_from.title, article_from.textではなくselect title, textでも可能ですが,わかりやすいようにテーブル名をつけておきます.

insert article_to (title, text)
select article_from.title, article_from.text
from article_from;
select * from article_to;
+----+----------+------------+
| id | title    | text       |
+----+----------+------------+
|  1 | abc      | test_text1 |
|  2 | xyz      | test_text2 |
|  3 | hogehoge | test_text3 |
|  4 | abc      | test_text1 |
|  5 | xyz      | test_text2 |
|  6 | hogehoge | test_text3 |
+----+----------+------------+

select句で取得した結果を登録するので,where句で取得するレコードを絞っておくこともできます.

insert article_to (title, text)
select article_from.title, article_from.text
from article_from
where id = 1;
select * from article_to;
+----+----------+------------+
| id | title    | text       |
+----+----------+------------+
|  1 | abc      | test_text1 |
|  2 | xyz      | test_text2 |
|  3 | hogehoge | test_text3 |
|  4 | abc      | test_text1 |
|  5 | xyz      | test_text2 |
|  6 | hogehoge | test_text3 |
|  7 | abc      | test_text1 |
|  8 | xyz      | test_text2 |
|  9 | hogehoge | test_text3 |
| 10 | abc      | test_text1 |
+----+----------+------------+
株式会社ゆめみ

Discussion