UPDATE と DELETE — 行の更新と削除 この記事は、基礎から複雑なSQL,SQLチューニングまでSQLの実践的なスキルを1からマスターする「SQL入門講座の一部」です。 UPDATEのSETによる複数列同時更新と計算式、DELETEの条件指定削除、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 — 全件削除の高速版とハイウォーターマーク