UPDATE と DELETE — 行の更新と削除 SQL の UPDATE と DELETE を基礎から解説します。SET による複数列の同時更新、WHERE による行の絞り込み削除、WHERE を書き忘れたときの全件更新・全件削除の挙動まで、ブラウザで実行しながら学べます。
UPDATE — 既存の行を書き換える INSERT が「新しい行を 追加 する」操作だったのに対し、UPDATE は すでに入っている行の値を書き換える 操作です。会員ステータスを変える、商品価格を改定する、購入数を更新するなど、運用中のアプリで日常的に使います。
基本の形は UPDATE 表名 SET 列 = 値 WHERE 条件; です。SET で「どの列をどんな値にするか」、WHERE で「どの行を対象にするか」を指定します。
-- customer テーブルの id = 1 の行の status を 'active' に書き換える
UPDATE customer SET status = 'active' WHERE id = 1 ;
-- 結果を確認
SELECT * FROM customer;
UPDATE 文の構造 UPDATE 表名 SET 列 = 値 WHERE 条件 対象の表 customer 更新内容 status = 'active' 対象の行 id = 1 対象の表 列を書き換え 行を絞る UPDATE 表名 が対象テーブル、SET 列 = 値 が更新内容、WHERE 条件 が対象行の絞り込みです。3 つの位置と役割を押さえます。WHERE を忘れると全行が更新される
UPDATE customer SET status = 'active' WHERE id = 1; から WHERE を抜くと (UPDATE customer SET status = 'active';)、テーブル customer の すべての行 の status が 'active' に書き換わります。エラーにはならないので、気付かないうちに本番データを丸ごと壊す事故になりやすい操作です。
顧客 1 名(Alice)の登録ステータスを保留から有効に切り替える、という要件を想定します。(正しく実行できれば解説が表示されます)
① まず SELECT name, status FROM customer WHERE id = 1; を実行し、Alice の status が 'pending'(= まだ active ではない)であることを確認してください。
② customer テーブルの `id = 1` の行(Alice)の status 列を 'active' に更新してください。
③ 最後に SELECT * FROM customer; を実行し、Alice の status だけが 'active' に変わり、Bob と Carol はそのままになっていることを確認してください。
(WHERE は SELECT 記事で扱った絞り込み条件と同じ書き方です)
複数列を同時に更新する SET 句では `列 = 値` をカンマ区切りで並べる ことで、複数の列を同時に更新できます。SET 列1 = 値1, 列2 = 値2, ... のように書きます。
値の右辺には その列自身を含む計算式 も書けます。たとえば SET price = price + 100 は、対象行の現在の price に 100 を足した値で書き換える、という意味になります。
SET 句のバリエーション 単一列 SET status = 'active' 複数列 (カンマ区切り) SET price = 200, stock = 100 計算式 (自分自身を参照) SET price = price + 100 組み合わせ SET price = price + 100, stock = stock - 10 SET には「列 = 値」を 1 組だけ書いても、カンマ区切りで複数並べてもよく、右辺には計算式も書けます。 -- 複数列を絶対値で同時に更新
UPDATE inventory SET price = 200 , stock = 100 WHERE id = 2 ;
-- 計算式で更新(既存値を参照する)
UPDATE inventory SET price = price + 100 , stock = stock - 10 WHERE id = 2 ;
在庫管理画面で「消しゴム(id=2)の価格と在庫数を見直したい」という要件を想定します。
① inventory テーブルの `id = 2` の行(消しゴム)について、price を 200、stock を 100 に 同時に 更新してください。
② 最後に SELECT * FROM inventory; を実行し、id=2 の行だけが新しい値に更新され、id=1(鉛筆)と id=3(ノート)はそのままになっていることを確認してください。
「鉛筆(id=1)の価格を 100 円アップ、在庫を 10 個ダウンしたい」という要件を想定します。SET の右辺に その列自身を含む計算式 を書くと、現在値からの相対変更ができます。
① inventory テーブルの `id = 1` の行(鉛筆)について、`price = price + 100` 、`stock = stock - 10` で 2 列を同時に更新してください。
② 最後に SELECT * FROM inventory WHERE id = 1; を実行し、鉛筆の price が 180、stock が 190 になっていることを確認してください。
DELETE — 行を削除する DELETE は テーブルから行を取り除く 操作です。基本の形は DELETE FROM 表名 WHERE 条件; で、WHERE で対象行を絞り込みます。SELECT のような列リスト(SELECT col1, col2)は不要で、行ごと丸ごと消す 操作になります。
テーブル定義(列構造)は残るので、削除後も同じテーブルにまた INSERT できます。テーブル自体を消したい場合は次の記事で扱う DROP TABLE / TRUNCATE を使います。
DELETE 文の構造 DELETE FROM 表名 WHERE 条件 対象の表 subscription 削除する行 status = 'expired' 対象の表 行を絞る DELETE FROM 表名 が対象テーブル、WHERE 条件 が削除対象の行を決めます。SELECT の列リストや UPDATE の SET 句にあたるものは DELETE には存在しません。-- 期限切れ(status = 'expired')の契約をすべて削除
DELETE FROM subscription WHERE status = 'expired' ;
-- 結果を確認(削除されなかった行だけが残る)
SELECT * FROM subscription;
サブスクリプション管理で「期限切れの契約をまとめてクリーンアップしたい」という要件を想定します。
① subscription テーブルから、`status` 列が `'expired'` の行を すべて 削除してください。
② 最後に SELECT * FROM subscription; を実行し、削除後に残っているのが status = 'active' の 2 行(Bob / Dave)だけになっていることを確認してください。
(WHERE 条件で絞り込んだ行が すべて 対象になります — id を指定しなくても、条件に合う複数行が一度に消えます)
WHERE 忘れに注意 — 全件更新・全件削除の落とし穴 UPDATE と DELETE で もっとも事故が多いのが WHERE の書き忘れ です。WHERE を書かないと、文法上はエラーにならず、対象が テーブル全行 に広がります。UPDATE 表 SET 列 = 値; で全行が同じ値に置き換わり、DELETE FROM 表; でテーブルが空になります。
壊れた直後に気付いても、確定したあとは戻せません。本番では 書き換える前に必ず同じ WHERE で `SELECT` を流して対象行を目視で確認 する、というのが運用での基本動作です。
WHERE あり と WHERE なし の挙動の違い DELETE FROM cache_entry WHERE id = 1; → id=1 の 1 行だけ削除 (WHERE で対象を絞っているので安全) DELETE FROM cache_entry; → すべての行が削除される (テーブルが空になる) UPDATE customer SET status = 'active' WHERE id = 1; → id=1 の 1 行だけ更新 (他の顧客はそのまま) UPDATE customer SET status = 'active'; → 全行の status が一括で 'active' に (顧客全員が有効状態になる) WHERE の有無だけで「1 行に絞った操作」と「全行への一括操作」が切り替わります。書き忘れの影響範囲は文字どおりテーブル全体です。 本番では SELECT で対象行を先に確認する
本番 DB への UPDATE / DELETE では、先に同じ WHERE で SELECT を流し、対象行が想定通りか目視で確認 してから書き換えに変える、という手順を踏むのが基本動作です。
手順は次の 2 ステップ:
1. SELECT * FROM 表名 WHERE 条件; で対象行を確認する(行数 / 値が想定通りか)
2. 想定どおりなら、同じ WHERE をそのまま UPDATE 表名 SET 列 = 値 WHERE 条件; や DELETE FROM 表名 WHERE 条件; に書き換えて実行する
WHERE 条件をコピペで使い回せるので、書き換えのときに WHERE を消し忘れる事故 も減らせます。
「キャッシュをすべて破棄して作り直したい」という要件を想定します。cache_entry テーブルは記事冒頭で 3 行のキャッシュが入っている状態です。
① WHERE を書かずに 、cache_entry の 全行を削除 する DELETE 文を実行してください。
② 最後に SELECT * FROM cache_entry; を実行し、結果が 0 行(空テーブル) になっていることを確認してください。
(WHERE 省略の DELETE は本番では事故の元ですが、ここでは挙動を体感するための題材として最終演習に置いています)
Q1 UPDATE 文の SET と WHERE の役割の説明として正しいものはどれですか。
SET は対象行を絞り込み、WHERE は更新後の値を指定する SET は更新する列と新しい値を指定し、WHERE は対象行を絞り込む SET と WHERE はどちらも対象行の絞り込みで、列の指定は別構文で行う SET はテーブル名の指定で、WHERE は更新する列を指定する
Q2 customer テーブルの id = 1 の行で、name と email の 2 列を 同時に 更新する正しい書き方はどれですか。
UPDATE customer SET name = 'Alice' AND email = 'alice@x.com' WHERE id = 1;UPDATE customer SET name = 'Alice', email = 'alice@x.com' WHERE id = 1;UPDATE customer SET name = 'Alice' SET email = 'alice@x.com' WHERE id = 1;UPDATE customer (name, email) VALUES ('Alice', 'alice@x.com') WHERE id = 1;
Q3 DELETE FROM product; のように WHERE を書かずに 実行するとどうなりますか。
WHERE が必須なので構文エラーで何も実行されない テーブル product がスキーマごと削除される(DROP TABLE と同じ) テーブル product の すべての行 が削除され、テーブル定義は残る 実行前に確認ダイアログが出て、Yes を選んだ場合だけ削除される
前へINSERT — テーブルにデータを追加する 次へ TRUNCATE — 全件削除の高速版とハイウォーターマーク