[MySQL] SELECT結果を連番を付けてINSERTする方法

3 min read

別テーブルからの INSERT なんて

INSERT INTO HOGE_TABLE 
SELECT ID, PASSWORD, ..., ..., 
FROM FOO;

こんな感じでやってしまえば入っちゃいますよね。

別テーブルから INSERT しつつ、連番も付けたい場合、どうすればいいか…
挿入先の行数をカウントしてプラス 1… こんな感じですかね…

INSERT INTO HOGE_TABLE 
SELECT (SELECT COUNT(NUMBER)+1 FROM HOGE_TABLE), ID, PASSWORD, ..., ..., 
FROM FOO;

ただ、これだとこんな感じで上手く連番になってくれません。

+--------+------+-----------+------+
| NUMBER |   ID |  PASSWORD |  ... |
+--------+------+-----------+------+
|      1 |    1 |  password |  ... |
|      1 |    2 |  password |  ... |
|      1 |    3 |  password |  ... |
|      1 |    4 |  password |  ... |
|      1 |    5 |  password |  ... |
|      1 |    6 |  password |  ... |
|      1 |    7 |  password |  ... |
|      1 |    8 |  password |  ... |
+--------+------+-----------+------+

ユーザ定義変数を利用する

ユーザ定義変数を使ってみます。
詳しくは「MySQL :: MySQL 5.1 リファレンスマニュアル (オンラインヘルプ) :: 5.4 ユーザー定義変数
上記のリファレンスによると、以下のように使えるようです。

mysql> SET @v1 = b'1000001';
mysql> SET @v2 = CAST(b'1000001' AS UNSIGNED), @v3 = b'1000001'+0;
mysql> SELECT @v1, @v2, @v3;
+------+------+------+
| @v1  | @v2  | @v3  |
+------+------+------+
| A    |   65 |   65 |
+------+------+------+

また、変数はクライアントが切断されたときに自動的に開放されるとのこと。

文字列も使えたりするみたいですが、今回は連番。数値と計算式を入れてみます。
なにやら SET も 1 文にまとめられるようですので以下のようにしてみました。

INSERT INTO HOGE_TABLE 
SELECT ( @row:=@row+1 ) AS NUMBER, ID, PASSWORD, ..., ...
FROM   ( SELECT @row:=0 ) AS DUMMY, FOO;

これで連番が挿入できます。普通に連番を作りたい場合もこれで良いのではないかと思います。
個人的にCOALESCE(MAX(連番を入れるカラム)+1,1)なんかより見やすくて好きです。