🦔
MySQL8.0で別テーブルでSELECTした結果をINSERTする
背景
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