insert into hoge select * from fuga join piyo using(id); みたいなSQLを書いてしまい、ただいま大変後悔しておりますのよ。かしこ
— yosio++ (@yosiopp) August 2, 2012
そんなわけで、今回は失敗談です。
insert into selectって便利ですよね。
なので上述のように使ってみたら、痛い目にあったよ、というお話。
テーブル構成はこんな感じ。(ホントは全然違うけど、イメージね)
hoge | |||
---|---|---|---|
_id* | id | num | val |
1 | 101 | 123 | foo |
fuga | |||
---|---|---|---|
_id* | id | num | val |
2 | 102 | 456 | bar |
3 | 103 | 789 | baz |
4 | 104 | 000 | qux |
piyo |
---|
id |
102 |
104 |
※ _id と id でややこしいけど、_idが主キー、idは外部キーだと思ってください。 んで、改めてSQLを見てみる。
insert into hoge select * from fuga join piyo using(id);
要は、hogeとfugaは全く同じ構成のテーブルで、
piyoっていうidリストとfugaを内部結合して得られた結果をhogeにつっこむ、ということをやろうとしてます。
が実際に実行すると、こうなる。
hoge | |||
---|---|---|---|
_id* | id | num | val |
1 | 101 | 123 | foo |
102 | 2 | 456 | bar |
104 | 4 | 000 | qux |
_idとidの値が逆になって入っちゃう。
普段あまり気にせずにselect * を使ってるけど、
usingを使用してjoinすると、結合キーが前に移動するので、
カラムは id, _id, num, val の順で出力されるわけです。
なので、上のSQLはつまり、
insert into hoge (_id, id, num, val)
select (id, _id, num, val) from fuga join piyo using(id);
と等価なんですね。
(※もちろん、_idとidの型が異なる場合はエラーになります。)
これからは insert into select * join using なんて横着はしないで、ちゃんとカラム名書きます。。。