MySQLのクエリには「REPLACE」があります。
今ではもう当たり前のように使用しているクエリですが、MySQLを学習する前にプログラミング言語を学習した私は、データベースのデータを引っ張り出してそれを配列から取り出し置き換えた後再度UPDATEでデータを更新するというなんとも遠回りな方法をしていました。
恐らくMySQLの学習を始めて間もない方の中には同じ方法でデータ更新をされている方も多いのではないでしょうか?
そこで今回はこの”REPLACE”についてわかりやすく解説をしてみたいと思います。
知ると非常に便利になるクエリですので最後までお付き合いください。
REPLACEとは

簡単に説明すると、MySQLのデータを更新する際にデータベース内で直接変更をするクエリです。
プログラミング言語には大体このメソッドが存在しますが、MySQLクエリにも存在します。
このクエリは、INSERT文とUPDATE文の良い所取りをしたようなクエリであり、REPLACEの最大のメリットでもあります。
挿入するデータが既にテーブルに存在した場合には新規でレコードを挿入せず、既存のレコードに新たなデータを上書きします。
逆にデータがテーブルに存在しない場合には、INSERT文と同じように新規レコードを挿入します。
データを指定してレコードを操作する

基本的な構文は次のようになります。
REPLACE INTO テーブル名 VALUES (値1[, 値2, ...]);
上記の構文ではデータのみ指定してレコードの置き換えや新規追加をします。
それでは早速、具体的に説明していきます。
まずREPLACEの使用にあたり、データベーステーブルを確認します。
# mysql -u root Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 816 Server version: 10.4.10-MariaDB mariadb.org binary distribution Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> use sample_db Database changed MariaDB [sample_db]> select * from users; +------+---------+------+ | id | name | age | +------+---------+------+ | 1 | Arex | 20 | | 2 | Jackson | 23 | | 3 | Liam | 16 | | 4 | Noah | 30 | | 5 | Aiden | 18 | | 6 | Caden | 25 | +------+---------+------+ 6 rows in set (0.001 sec)
今回使用するのは「sample_db」の中に予め作成しておいた「users」という名前のテーブルです。
この中身の一つを先ほど構文を記述したREPLACEを使って変更をかけてみましょう。
MariaDB [sample_db]> replace into users
-> values (
-> '4',
-> 'beth',
-> 15
-> );
Query OK, 2 rows affected (0.001 sec)
MariaDB [sample_db]> select * from users;
+----+---------+------+
| id | name | age |
+----+---------+------+
| 1 | Arex | 20 |
| 2 | Jackson | 23 |
| 3 | Liam | 16 |
| 4 | beth | 15 |
| 5 | Aiden | 18 |
| 6 | Caden | 25 |
+----+---------+------+
6 rows in set (0.000 sec)
上のサンプルではidが4のデータのnameとageにそれぞれREPLACEを使い置換を実行しました。
置換後にSELECT文で検索表示させると、元々「Noah」だった内容が「beth」に、ageカラムが「30」から「15」に置き換えられていることがわかります。
では次はカラム名も指定して置き換える方法について解説していきます。
カラム名とデータを指定したレコード置換

カラム名とデータをそれぞれ指定して置き換える場合には以下のような記述に変わります。
REPLACE INTO テーブル名(フィールド1[, フィールド2, ...) VALUES (値1[, 値2, ...]);
先ほどの基本形の構文に今度はフィールド名が追加されています。
ではこちらも実際に見てみましょう。
次のコマンドをご覧ください。
MariaDB [sample_db]> replace into users
-> (
-> name,
-> age
-> ) values (
-> 'Andy',
-> 50
-> );
Query OK, 1 row affected, 1 warning (0.003 sec)
MariaDB [sample_db]> select * from users;
+----+---------+------+
| id | name | age |
+----+---------+------+
| 0 | Andy | 50 |
| 1 | Arex | 20 |
| 2 | Jackson | 23 |
| 3 | Liam | 16 |
| 4 | beth | 15 |
| 5 | Aiden | 18 |
| 6 | Caden | 25 |
+----+---------+------+
7 rows in set (0.000 sec)
上記サンプルではレコードの指定は行わず、nameとageにそれぞれ「Andy」と「50」を指定してレコード置換を実行しています。
今回は”id”の指定をせず置換を行ったため、デフォルトで”not null”と”Auto increment”が付帯されているidの先頭にデータが新規追加されていることが確認できます。
これは、今回使用しているテーブルのidカラムにはnullまたは””を指定することで強制的に「0」が挿入されるような構造となっているため、レコードの先頭に新規で挿入されたわけです。
SELECTを使った置換

REPLACEのもう一つの使い方としては、SELECT文を使って検索した結果を基に置換を行う方法があります。
構文は以下の通りです。
REPLACE INTO テーブル名 SELECT(フィールド1[, フィールド2, ...) FROM テーブル名 (WHERE [条件]);
上記の構文について簡単に説明します。
REPLACE INTO テーブル名に続けて、SELECT文を入力します。条件検索も可能なので、条件を指定する場合にはWHEREなどの条件を追加してください。
実際にコマンドを見てみましょう。
MariaDB [sample_db]> select * from sample_table_a; +------+---------+------+ | id | name | age | +------+---------+------+ | P001 | Andy | 50 | | P002 | Arex | 20 | | P003 | Jackson | 23 | | P004 | Liam | 16 | | P005 | beth | 15 | | P006 | Aiden | 18 | | P007 | Caden | 25 | +------+---------+------+ 7 rows in set (0.000 sec) MariaDB [sample_db]> select * from sample_table_b; +------+-----------+-----+ | id | name | age | +------+-----------+-----+ | U001 | aoki | 21 | | U002 | takahashi | 25 | | U003 | hashimoto | 42 | | U004 | miyake | 16 | | U005 | tokiwa | 52 | +------+-----------+-----+ 5 rows in set (0.000 sec)
2つのテーブルがあります。この二つのうち、”sample_table_a”に”sample_table_b”のレコードを追加してみます。
MariaDB [sample_db]> replace into sample_table_a
-> select * from sample_table_b
-> where
-> id = 'U003';
Query OK, 1 row affected (0.004 sec)
Records: 1 Duplicates: 0 Warnings: 0
MariaDB [sample_db]> select * from sample_table_a;
+------+-----------+------+
| id | name | age |
+------+-----------+------+
| P001 | Andy | 50 |
| P002 | Arex | 20 |
| P003 | Jackson | 23 |
| P004 | Liam | 16 |
| P005 | beth | 15 |
| P006 | Aiden | 18 |
| P007 | Caden | 25 |
| U003 | hashimoto | 42 |
+------+-----------+------+
8 rows in set (0.000 sec)
“sample_table_b”のレコードのうち「U003」に該当するレコードを条件検索し、そのレコードを丸ごと”sample_table_a”に置換できていることが確認できました。
まとめ

いかがでしたか?
今回はMySQLのREPLACEクエリについて解説してみました。
MySQLは他のプログラミング言語と違い、REPLACEを使うとINSERTもしくはUPDATEを自動で判断してくれるので開発側で判断する必要がありません。
コマンドも単純なため簡単に覚えることが出来、実用性も十分にあります。
今からMySQLの学習を始める方でも苦労なく覚えられますので、こういったクエリはどんどん覚えて使うようにすると作業効率がグンと上がります。