ひとり勉強ログ

ITエンジニアの勉強したことメモ

MySQL講座#11 データの更新(UPDATE文の使い方)

テーブルにINSERT文でデータを登録した後、登録済みのデータを変更したいと思うことがある。例えば、「超人の身長を間違えて登録してしまった」などである。そんなとき、データを削除して再登録するなどという面倒な方法をとる必要はない。UPDATE文によって、テーブルのデータを変更することが可能。

UPDATE文は、INSERT文やDELETE文と同じくDML文に属する。これを利用することで、テーブルのデータを変更することができる。基本的な構文は以下の通り。

UPDATE <テーブル名> SET <列名> = <式>

更新対象の列と、更新後の値は、SET句に記述する。

それではまず、chojinテーブルのcrated列(登録日)を全行、「2020年2月9日」で統一してみる。

UPDATE chojin
SET created = '2020-02-09';

結果

+------+--------------------------------+------------+
| id   | name                           | created    |
+------+--------------------------------+------------+
| 0001 | キン肉マン                     | 2020-02-09 |
| 0002 | テリーマン                     | 2020-02-09 |
| 0003 | ロビンマスク                   | 2020-02-09 |
| 0004 | ウォーズマン                   | 2020-02-09 |
| 0005 | ラーメンマン                   | 2020-02-09 |
| 0006 | ブロッケンJr                 | 2020-02-09 |
| 0007 | ウルフマン                     | 2020-02-09 |
以下省略

条件を指定したUPDATE文(探索型UPDATE)

次に、全行更新するのではなく、更新対象の行を制限してみる。行を制限するには、DELETE文のときと同様、WHERE句を使うことで可能。こういう対象行を制限したUPDATE文のことを、「探索型UPDATE」と呼ぶ。構文は次の通り。

UPDATE <テーブル名>
SET <列名> = <式>
WHERE <条件>;

例えば、categoryが「正義超人」の行に限って、超人強度(power)を10倍にするには、以下のように書く。

現状のデータ。

SELECT id, name, power FROM chojin WHERE category = '正義超人';

結果

+------+--------------------------+-------+
| id   | name                     | power |
+------+--------------------------+-------+
| 0001 | キン肉マン               |    95 |
| 0002 | テリーマン               |    95 |
| 0003 | ロビンマスク             |    96 |
| 0004 | ウォーズマン             |   100 |
| 0005 | ラーメンマン             |    97 |
| 0006 | ブロッケンJr           |    90 |
| 0007 | ウルフマン               |    80 |
| 0043 | スペシャルマン           |     0 |
| 0044 | カナディアンマン         |     0 |
+------+--------------------------+-------+

UPDATE文を実行。

UPDATE chojin
SET power = power * 10
WHERE category = '正義超人';

結果

+------+--------------------------+-------+
| id   | name                     | power |
+------+--------------------------+-------+
| 0001 | キン肉マン               |   950 |
| 0002 | テリーマン               |   950 |
| 0003 | ロビンマスク             |   960 |
| 0004 | ウォーズマン             |  1000 |
| 0005 | ラーメンマン             |   970 |
| 0006 | ブロッケンJr           |   900 |
| 0007 | ウルフマン               |   800 |
| 0043 | スペシャルマン           |     0 |
| 0044 | カナディアンマン         |     0 |
+------+--------------------------+-------+

値を元に戻す。

UPDATE chojin
SET power = power / 10
WHERE category = '正義超人';

結果

+------+--------------------------+-------+
| id   | name                     | power |
+------+--------------------------+-------+
| 0001 | キン肉マン               |    95 |
| 0002 | テリーマン               |    95 |
| 0003 | ロビンマスク             |    96 |
| 0004 | ウォーズマン             |   100 |
| 0005 | ラーメンマン             |    97 |
| 0006 | ブロッケンJr           |    90 |
| 0007 | ウルフマン               |    80 |
| 0043 | スペシャルマン           |     0 |
| 0044 | カナディアンマン         |     0 |
+------+--------------------------+-------+

NULLで更新するには

NULLのデータで更新するため、列「created」のNOT NULL制約を外す。

ALTER TABLE chojin MODIFY COLUMN created DATE;
SHOW COLUMNS FROM chojin;
+-----------+--------------+------+-----+---------+-------+
| Field     | Type         | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| id        | char(4)      | NO   | PRI | NULL    |       |
| name      | varchar(100) | NO   |     | NULL    |       |
| kana      | varchar(100) | NO   |     | NULL    |       |
| category  | varchar(100) | NO   |     | NULL    |       |
| attribute | varchar(100) | YES  |     | NULL    |       |
| height    | int(11)      | YES  |     | NULL    |       |
| weight    | int(11)      | NO   |     | NULL    |       |
| power     | int(11)      | NO   |     | NULL    |       |
| origin    | varchar(100) | NO   |     | NULL    |       |
| created   | date         | YES  |     | NULL    |       |
+-----------+--------------+------+-----+---------+-------+

UPDATEを使うことで、列をNULLで更新することもできる。例えば、idが「0043」のスペシャルマンと「0044」のカナディアンマンの登録日(created)をNULLにしてみる。

UPDATE chojin
SET created = NULL
WHERE id IN ('0043', '0044');

結果

+------+--------------------------+---------+
| id   | name                     | created |
+------+--------------------------+---------+
| 0043 | スペシャルマン           | NULL    |
| 0044 | カナディアンマン         | NULL    |
+------+--------------------------+---------+

複数列の更新

UPDATEのSET句には、複数の列を対象として記述することが可能。上記で正義超人の超人強度を10倍にしたが、同時に身長に50を加える場合どうしたら良いか。

同様に2つのUPDATE文で実行することは可能である。それはそれで正しく更新は行われるが、二度もUPDATE文を実行するのは無駄であるし、SQLの記述量も増える。1つのUPDATE文にまとめて書けば良い。以下、2種類の方法がある。

UPDATE文を1つにまとめる方法①

UPDATE chojin
SET power = power * 10,
height = height + 50
WHERE category = '正義超人';

UPDATE文を1つにまとめる方法②

UPDATE chojin
SET (power, height) = (power * 10, height + 50)
WHERE category = '正義超人';

もちろん、SET句は2列だけでなく、3列並べることも可能。

注意が必要なのは、列をカンマで区切って並べる①の方法は、どのDBMSでも利用することが可能な一方、列をリスト化する②の方法は、一部のDBMSでしか利用できないことである。したがって、基本的には①の方法を使うのが確実である。