PostgreSQL でデータを更新 (UPDATE) する複数の方法

PostgreSQL のデータ更新 (UPDATE) 機能

PostgreSQL は標準 SQL に準拠しており、かつ独自の高度な機能を持ち合わせており、データベースでデータを更新する方法も複数用意されています。そこで PostgreSQL のデータを UPDATE する複数の方法を紹介します。

これを知っていると、データを効率よく更新出来るようになります。




テスト用のテーブル作成

まず最初に非常に簡単なテーブルを PostgreSQL データベースに作成し、そのテーブルに存在するデータに対して様々な方法でデータを UPDATE していきます。
CREATE TABLE colors (
  id int,
  name text
);

=> SELECT * FROM colors;
+----+--------+
| id |  name  |
+----+--------+
|  1 | red    |
|  2 | blue   |
|  3 | yellow |
|  4 | orange |
|  5 | white  |
|  6 | black  |
|  7 | pink   |
|  8 | gray   |
+----+--------+
(8 rows)


基本的な UPDATE 文

最もシンプルな UPDATE 文は次のようになります。"UPDATE テーブル名 SET 列名 = 新しい値 WHERE 条件" という書式です。
UPDATE colors
  SET name = 'Japan'
WHERE id = 1;

次のように複数の列名を一度に UPDATE することも出来ます。
UPDATE colors
  SET name = 'Japan',
      id = 99
WHERE id = 2;


もしある列にデフォルト値の設定がある場合には UPDATE 文で設定する値を DEFAULT と指定することで、テーブルで定義されたデフォルト値を自動的に設定してくれます。
CREATE TABLE colors (
  id serial,
  name text DEFAULT 'pikachu'
);

-- "name" 列にデフォルト値を指定
UPDATE colors
  SET name = DEFAULT
WHERE id = 1;

-- "name" 列にデフォルト値が設定された
=> SELECT * FROM colors;
+----+---------+
| id |  name   |
+----+---------+
|  1 | pikachu |
+----+---------+
(1 row)


テーブルを結合 (JOIN) してデータを UPDATE する

PostgreSQL の UPDATE 文では FROM キーワードを書くことによって、結合したテーブルのデータを使ってデータを UPDATE することが出来ます。実際に例を見てみましょう。


まず以下のように色の名前が英語と日本語で登録されている2つのテーブルを用意します。英語の色の名前が入ったテーブルの名前を、全て日本語の色の名前に変更する場合を考えます。
=> SELECT * FROM colors;
+----+--------+
| id |  name  |
+----+--------+
|  1 | red    |
|  2 | blue   |
|  3 | yellow |
|  4 | orange |
|  5 | white  |
|  6 | black  |
|  7 | pink   |
|  8 | gray   |
+----+--------+
(8 rows)

=> SELECT * FROM color_jp ;
+----+---------+
| id | name_jp |
+----+---------+
|  1 | 赤      |
|  2 | 青      |
|  3 | 黄      |
|  4 | 橙      |
|  5 | 白      |
|  6 | 黒      |
|  7 | ピンク  |
|  8 | 灰      |
+----+---------+
(8 rows)

ここで2つのテーブルを結合できたら非常に便利です。実際に UPDATE 文の中でテーブルを結合 (JOIN) して、他のテーブルのデータを使ってデータを更新してみます。このように他のテーブルと結合できる機能は PostgreSQL の強力な機能の1つです。
=>
UPDATE colors
  SET name = color_jp.name_jp
FROM color_jp
WHERE colors.id = color_jp.id;

UPDATE 8


=> SELECT * FROM colors;
+----+--------+
| id |  name  |
+----+--------+
|  1 | 赤     |
|  2 | 青     |
|  3 | 黄     |
|  4 | 橙     |
|  5 | 白     |
|  6 | 黒     |
|  7 | ピンク |
|  8 | 灰     |
+----+--------+
(8 rows)