コース一覧
SQL実践:JOIN・サブクエリ・データ更新
UPDATE 文でデータを更新する

SQL実践:JOIN・サブクエリ・データ更新

JOIN、集合演算、サブクエリ、CTE、DDL・DMLを学び、複数テーブルを組み合わせてデータベースを作成・更新する無料コースです。

1
テーブル結合
01. なぜ結合が必要か5分
02. INNER JOINの基本5分
03. LEFT/RIGHT OUTER JOIN5分
04. 複数テーブルの結合5分
05. 自己結合5分
06. 集合演算 UNION/INTERSECT/EXCEPT5分
07. 結合の実践演習5分
08. テーブル結合クイズ5分
2
サブクエリ活用
01. サブクエリとは5分
02. WHERE句のサブクエリ5分
03. FROM句のサブクエリ5分
04. SELECT句のサブクエリ5分
05. WITH句(CTE)の活用5分
06. サブクエリ実践クイズ5分
3
テーブル作成とデータ操作
01. CREATE DATABASE と CREATE TABLE5分
02. データ型の選び方5分
03. INSERT 文でデータを追加する5分
04. UPDATE 文でデータを更新する5分
05. DELETE 文でデータを削除する5分
06. 物理削除と論理削除5分
07. ALTER TABLE で構造を変更する5分
08. 制約 (NOT NULL / UNIQUE / DEFAULT)5分
09. TRUNCATE と DROP5分
10. DDL / DML 実践クイズ5分

UPDATE 文でデータを更新する

WHERE が決めるのは範囲

1 人だけ直すつもりが、全員書き換わる

会員 1 人を無料プランに戻したくて、こう打ったとします。

SQL クエリ

UPDATE members SET plan = 'free';

WHERE がありません。これで全会員が無料プランになります。データベースはこれを事故と見なさず、正常終了として「更新した件数」を返すだけです。しかも UPDATE は元の値を上書きする命令なので、誰がどのプランだったかは、どこにも残りません。

正しくは、WHERE で対象を絞ります。

SQL クエリ

UPDATE members
SET    plan = 'free',
       updated_at = NOW()
WHERE  id = 47;

SET に「何を入れるか」、WHERE に「どの行か」を書きます。変えたい列が複数あるときは、SET の中をカンマで並べます。構文としてはこれだけで、難しいのは 2 行目ではなく 4 行目のほうです。

流す前に、同じ WHERE のまま SELECT する

UPDATE を書いたら、実行する前に必ず先頭を SELECT に置き換えて、WHERE はそのままで一度流します。

SQL クエリ

-- 1. まず対象を見る  ここで件数と中身を確認する
SELECT id, name, plan
FROM   members
WHERE  plan = 'trial' AND created_at < '2026-01-01';

-- 2. 想定どおりなら、WHERE をそのままにして UPDATE を流す
UPDATE members
SET    plan = 'free'
WHERE  plan = 'trial' AND created_at < '2026-01-01';

5 件のつもりが 3,000 件返ってきた、という食い違いは、この一手間があるときにだけ見つかります。条件を AND で 2 つ以上つないだときほど効きます。片方を書き落としていても SQL 自体は正しく動いてしまうので、動いたかどうかでは気付けないからです。

WHERE は書き直さず、コピーして貼ってください。手で打ち直すと、確認したものと流すものが別物になります。

今入っている値を使って、足し引きする

SET の右辺には、その行に今入っている値も書けます。

SQL クエリ

UPDATE members
SET    point = point - 500
WHERE  id = 47;

point = point - 500 は「今の point から 500 を引いた値を入れる」という意味です。掛け算も同じように書けます。

この書き方には、読んでから書き戻すまでの往復が要らないという利点があります。アプリ側で今の値を取得し、計算して、書き戻す、という手順を踏むと、その間に別の処理が同じ行を更新したときに、片方の変更が消えます。データベースの中で計算させれば、その隙間がなくなります。

全部通すか、全部なかったことにするか

引く側と足す側が対になっている処理では、片方だけ成功した状態が一番困ります。口座の振替がその典型です。

SQL クエリ

BEGIN;
UPDATE accounts SET balance = balance - 5000 WHERE id = 1;
UPDATE accounts SET balance = balance + 5000 WHERE id = 2;
COMMIT;

BEGIN から COMMIT までがひとかたまりになり、途中で止まっても中途半端な状態は残りません。COMMIT していない変更は、他の接続からはまだ見えていません。

途中でエラーが出たときは ROLLBACK で BEGIN の直後まで戻します。

SQL クエリ

BEGIN;
UPDATE accounts SET balance = balance - 5000 WHERE id = 1;
-- ここでエラーに気づいた
ROLLBACK;

エラーを見ずに COMMIT すると、引いたけれど足していない状態が確定します。 戻せるのは COMMIT の前だけなので、失敗したかどうかを確かめてから閉じる、という順番が要ります。

COMMIT も ROLLBACK も打たずに放置するのも事故のもとです。掴んだ行が解放されないので、同じ行を触ろうとした別の接続が待たされたまま止まります。開けたら必ず閉じる、と覚えてください。

テーブル構造

CREATE TABLE products (
  id INT PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  price INT NOT NULL,
  stock INT NOT NULL,
  category_id INT NOT NULL
);

INSERT INTO products (id, name, price, stock, category_id) VALUES
  (1, 'ノートPC',         100000, 10, 1),
  (2, 'ワイヤレスマウス',   3000,  50, 1),
  (3, '外付けSSD 1TB',    14000,  20, 1),
  (4, 'ボールペン',          150, 200, 2),
  (5, 'ノートB5',            200, 300, 2);

期待される出力

idnamepricestock
1ノートPC1000007
2ワイヤレスマウス300050
3外付けSSD 1TB1400020
4ボールペン165200
5ノートB5220300

ヒント

stock = stock - 3 のように既存列を参照して引き算できる

10% 値上げは price = FLOOR(price * 1.1) のように書く

UPDATE は WHERE で必ず対象を絞ること

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • データベースデータを構造化して保存する仕組み
  • SQLデータベースを操作するための共通言語
  • 処理計算や代入を表す長方形
query.sql
学習モード
エディタを読み込んでいます
コードの実行結果
データベースを初期化中...