SQLのDELETE文は、テーブルから不要になったデータ(行)を削除するための命令です。本記事では、基本の書き方から、条件を指定した削除、サブクエリや結合を使った削除、誤って消さないための注意点、TRUNCATE文との違いまでを、実行結果つきで解説します。動作はMySQLで確認しています。
DELETE文とは
SQLの「DELETE」とは、データを削除するクエリです。条件を指定しなければ、テーブル内のレコードがすべて削除されますが、WHERE句を併用すれば条件を満たすレコード(行)のみを削除することもできます。
DELETE文は条件にあてはまるレコード(行)を削除する
DELETE文は、指定されたテーブルを参照し、指定された条件に合致するレコード(行)を削除します。該当するレコードが複数ある場合は、そのレコードがすべて削除されます。また条件を指定しない場合は、テーブルのデータがすべて削除されます。なお、データを全件削除しても、テーブルの枠組み自体は残ります。テーブル自体を削除するには、DROP TABLE文を使います。
DELETE文の文法・使い方はデータベースによって異なる
DELETE文の文法は、RDBMS(リレーショナルデータベース管理システム)やデータベースのバージョンによっても異なる場合があります。エラーや意図しない動作を招きかねないので事前に使用するRDBMSやバージョンを把握し、使い方を調べておく必要があります。MySQLの構文は、MySQL公式リファレンスマニュアルのDELETEステートメントで確認できます。
DELETE文の使い方
基本構文
【全レコードの削除】
テーブルに格納されたすべてのレコードを削除する場合は次の構文になります。
DELETE FROM テーブル名;
【削除するレコードの条件を指定する】
削除するレコードの条件を指定する場合は次の構文になります。WHERE句は、SELECT文やUPDATE文だけでなくDELETE文にも使用できます。WHERE句の書き方は、以下の記事で解説しています。
DELETE FROM テーブル名 WHERE 条件;
MySQLは初期設定で「オートコミット」(1文ごとに変更を確定する)になっているため、DELETE文は実行した瞬間に削除が確定し、あとから元に戻せません。
DELETE文の動作を確認する場合は実行前に
BEGIN;
DELETE文の実行後に
ROLLBACK;
を記述することで、ロールバックできます(削除前の状態に戻せます)。削除結果に問題がなければ、ROLLBACKの代わりにCOMMITを実行して確定します。トランザクションの使い方は、MySQL公式リファレンスのSTART TRANSACTION、COMMITおよびROLLBACKのページで確認できます。
≫まずは簡単60秒で無料お問い合わせから≪
サンプルテーブル
「DELETE」文の具体的な使い方を解説していくにあたって、サンプルとして「生徒(student)」テーブルと「テスト(test)」を用意しました。
「生徒(student)」テーブル
| 氏名(name) | クラス(class) | 学籍番号(student_no) |
| 秋山 | A | 997 |
| 久保田 | A | 998 |
| 佐々木 | B | 999 |
| 佐藤 | B | 1000 |
| 鈴木 | B | 1001 |
| 田中 | C | 1002 |
| 土屋 | C | 1003 |
「テスト(test)」テーブル
| ID(id) | 英語(en) | 数学(ma) | 国語(ja) |
| 997 | 80 | 70 | 90 |
| 998 | 100 | 100 | 100 |
| 1000 | 85 | 80 | 85 |
| 1001 | 75 | 40 | 40 |
| 1002 | 60 | 65 | 35 |
| 1003 | 90 | 95 | 90 |
テーブルのデータをすべて削除する
テーブルに含まれるデータすべてを削除する場合は次のように「DELETE FROM テーブル名」と記述します。なお、データを全件削除しても、テーブルの枠組み自体は残ります。
【実行コード】
DELETE FROM student;
実行後は「生徒」テーブルのデータを検索しても、表示されないか「表示される結果がありません」という結果が出ます。なお、大量のデータを全件削除する場合は、後述するTRUNCATE文のほうが高速です。
条件にあてはまるレコード(行)を削除する
DELETE文は、データの一部を削除する場合が多いでしょう。条件は、WHERE句で指定できます。ここでは「生徒」テーブルのうち、Aクラスの生徒を消してみます。
【実行コード】
DELETE FROM student WHERE class='A';
文字列の値はシングルクォーテーション(’)で囲みます。囲まずに「class=A」と書くと、Aがカラム名とみなされ「ERROR 1054 (42S22): Unknown column ‘A’ in ‘where clause’」というエラーになります。
MySQLのコマンドラインで実行すると「Query OK, 2 rows affected」のように、削除された行数が表示されます。想定どおりの行数かを確認しておきましょう。
【実行結果】
| 氏名(name) | クラス(class) | 学籍番号(student_no) |
| 佐々木 | B | 999 |
| 佐藤 | B | 1000 |
| 鈴木 | B | 1001 |
| 田中 | C | 1002 |
| 土屋 | C | 1003 |
WHERE句は不等号も使えます。学籍番号が1000以上の生徒を削除してみます。
【実行コード】
DELETE FROM student WHERE student_no>=1000;
【実行結果】
| 氏名(name) | クラス(class) | 学籍番号(student_no) |
| 秋山 | A | 997 |
| 久保田 | A | 998 |
| 佐々木 | B | 999 |
削除するデータをSELECT文で指定する
削除するデータを数値や文字列で示すこともできますが、SELECT文でも指定可能です。ここでは「テスト」テーブルにIDがない(テストを受けていない)生徒を「生徒」テーブルから削除します。
【実行コード】
DELETE FROM student WHERE student_no NOT IN (SELECT id FROM test);
カッコ内のSELECT文で「テスト」テーブルのIDの一覧を取り出し、その中に含まれない学籍番号の生徒を削除しています。テストを受けていない佐々木さん(999)だけが削除されます。IN句・NOT IN句の使い方は、以下の記事で解説しています。
【実行結果】
| 氏名(name) | クラス(class) | 学籍番号(student_no) |
| 秋山 | A | 997 |
| 久保田 | A | 998 |
| 佐藤 | B | 1000 |
| 鈴木 | B | 1001 |
| 田中 | C | 1002 |
| 土屋 | C | 1003 |
上位/下位のデータを削除する
MySQLのDELETE文では、「ORDER BY」句で並び順を決め、「LIMIT」句で件数を指定することで、上位または下位のデータだけを削除できます。
学籍番号の大きい順に2件(土屋さんと田中さん)を削除する場合は以下のようなコードになります。
【実行コード】
DELETE FROM student ORDER BY student_no DESC LIMIT 2;
【実行結果】
| 氏名(name) | クラス(class) | 学籍番号(student_no) |
| 秋山 | A | 997 |
| 久保田 | A | 998 |
| 佐々木 | B | 999 |
| 佐藤 | B | 1000 |
| 鈴木 | B | 1001 |
次は、「テスト」テーブルの英語の点数を降順に並べて上位3件を削除します。
【実行コード】
DELETE FROM test ORDER BY en DESC LIMIT 3;
【実行結果】
| ID(id) | 英語(en) | 数学(ma) | 国語(ja) |
| 997 | 80 | 70 | 90 |
| 1001 | 75 | 40 | 40 |
| 1002 | 60 | 65 | 35 |
英語の点数が高い998(100点)、1003(90点)、1000(85点)の3件が削除されました。「DESC」を「ASC」に書き換えると昇順になり、点数の低い3件を削除できます。
なお、DELETE文でのORDER BYとLIMITはMySQL(MariaDB)独自の書き方です。PostgreSQLやSQL Serverでは使えないため、サブクエリなど別の方法で対象を指定します。各データベースの書き方は、PostgreSQLのDELETE、SQL ServerのDELETEの公式ドキュメントで確認できます。並べ替えに使うORDER BY句の使い方は、以下の記事で解説しています。
前方一致や後方一致で条件を指定し削除する
LIKE演算子を使えば、前方一致や後方一致といった削除条件を指定することも可能です。「%」は0文字以上の任意の文字列を表し、「’田%’」なら「田」で始まる、「’%田’」なら「田」で終わる、という意味になります。ここでは氏名が「田」で終わる生徒(久保田さん)を削除します。LIKEの仕様はMySQL公式リファレンスの文字列比較関数および演算子のページで確認できます。使い方は、以下の記事で解説しています。
【実行コード】
DELETE FROM student WHERE name LIKE '%田';
【実行結果】
| 氏名(name) | クラス(class) | 学籍番号(student_no) |
| 秋山 | A | 997 |
| 佐々木 | B | 999 |
| 佐藤 | B | 1000 |
| 鈴木 | B | 1001 |
| 田中 | C | 1002 |
| 土屋 | C | 1003 |
別のテーブルと結合して削除する
「JOIN」句で別のテーブルと結合し、両方のテーブルに共通するデータを削除することもできます。
テストを受けた生徒を「生徒」テーブルから削除します。
(「生徒」テーブルと「テスト」テーブルの2つのテーブルに共通するデータを「生徒」テーブルから削除する)
【実行コード】
DELETE student FROM student INNER JOIN test ON student.student_no = test.id;
「DELETE」と「FROM」の間に書いたテーブル(ここではstudent)の行だけが削除されます。testテーブルは結合条件に使われるだけで、データは削除されません。この書き方はMySQLのもので、結合を使ったDELETEの書き方はデータベースによって異なります。JOIN句の使い方は、以下の記事で解説しています。
【実行結果】
| 氏名(name) | クラス(class) | 学籍番号(student_no) |
| 佐々木 | B | 999 |
DELETEにサブクエリを使用
英語の点数が平均点(81.67点)より低い生徒を「生徒」テーブルから削除します。まずは、英語の点数が平均点より低い生徒のIDを「テスト」テーブルから抽出します。
SELECT id FROM test WHERE en < (SELECT AVG(en) FROM test);
カッコ内のSELECT文で平均点を求め、それより低い997(80点)、1001(75点)、1002(60点)の3件が抽出されます。
このSELECT文をDELETE文のWHERE句に入れると、該当する生徒を削除できます。いきなりDELETE文を書かずに、先にSELECT文で対象を確認してから組み込むと安全です。
【実行コード】
DELETE FROM student WHERE student_no IN (SELECT id FROM test WHERE en < (SELECT AVG(en) FROM test));
【実行結果】
| 氏名(name) | クラス(class) | 学籍番号(student_no) |
| 久保田 | A | 998 |
| 佐々木 | B | 999 |
| 佐藤 | B | 1000 |
| 土屋 | C | 1003 |
秋山さん・鈴木さん・田中さんの3人が削除されました。
また、EXISTSを使って「別のテーブルに対応する行があるかどうか」で削除することもできます。次の例は、先ほどの「テストを受けていない生徒を削除する」をNOT EXISTSで書き直したもので、実行結果は同じ(佐々木さんだけが削除される)です。
DELETE FROM student WHERE NOT EXISTS (SELECT 1 FROM test WHERE test.id = student.student_no);
カッコ内のサブクエリは、「生徒」テーブルの1行ごとに、その生徒の学籍番号が「テスト」テーブルにあるかを調べます。このように外側のテーブルを参照するサブクエリを「相関サブクエリ」と呼び、DELETE文やUPDATE文でよく使われます。EXISTSの仕様はMySQL公式リファレンスのEXISTSのページで確認できます。使い方は、以下の記事で解説しています。
特定のカラム(列)を削除する場合
DELETE文では特定のカラム(列)のデータのみを削除することはできません。ただ、UPDATE文を使うことで、特定のフィールドをNULL値や空白に更新することが可能です。UPDATE文の使い方は、以下の記事で解説しています。
【実行コード】
UPDATE test SET en = NULL;
【実行結果】
| ID(id) | 英語(en) | 数学(ma) | 国語(ja) |
| 997 | NULL | 70 | 90 |
| 998 | NULL | 100 | 100 |
| 1000 | NULL | 80 | 85 |
| 1001 | NULL | 40 | 40 |
| 1002 | NULL | 65 | 35 |
| 1003 | NULL | 95 | 90 |
DELETE文を使用する上での注意点
DELETE文を使う上で、留意すべき点がいくつかあります。
特定の部分だけを削除することはできない
DELETE文は、条件に該当するレコードごと削除するため、該当するレコードの特定の列に格納されたデータだけを削除するといったことはできません。
ただ、その箇所が「NULL」でもいいという場合はUPDATE文を活用して、値をNULLに更新することもできます。
列の削除には使えない
DELETE文はレコード(行)ごとの削除であってカラム(列)ごとの削除はできません。その場合はALTER TABLE文に「DROP カラム名」で行なえます(MySQL公式リファレンスのALTER TABLEステートメント)。ALTER TABLE文の使い方は、以下の記事で解説しています。
ただ、カラムを削除することで次のような不都合が生じる可能性があるため、カラムを削除する際は十分注意する必要があります。
- ほかのテーブルやビューからデータを参照できなくなり、正常にデータを保存できなくなる
- プログラムからデータを参照できず、正常に動作しなくなる
データを正しく削除できるか確認する
WHERE句で条件を指定する場合は、まずSELECT文で抽出されるデータが意図したものであるか確認を取ってからDELETE文を使いましょう。はじめからDELETE文を使うと、削除対象を誤っていた場合に消すべきでないデータまで消去してしまい、大きなトラブルになりかねません。
特に注意したいのがWHERE句の書き忘れです。WHERE句がないDELETE文は、テーブルのすべての行を削除します。オートコミットのMySQLでは実行した時点で確定するため、次の手順で実行すると安全です。
- 削除したい条件でSELECT文を実行し、対象の行と件数を確認する
- BEGINでトランザクションを開始し、SELECT文と同じWHERE句でDELETE文を実行する
- 表示された削除件数(○ rows affected)がSELECT文の件数と同じなら COMMIT、違えば ROLLBACK する
SELECT * FROM student WHERE class='A'; -- ①対象を確認(2件)
BEGIN; -- ②トランザクション開始
DELETE FROM student WHERE class='A'; -- 2 rows affected
COMMIT; -- ③件数が合えば確定(違えばROLLBACK;)
削除するデータがほかのテーブルに影響しているか確認する
削除する前にデータがほかのテーブルやビューから参照されていると、削除後に問題が発生するので削除しても問題がないか十分にチェックしましょう。ほかのテーブルから参照されているかは、外部キーの設定から確認できます。外部キーについては、以下の記事で解説しています。
実務ではデータを削除する代わりに、テーブルに「削除フラグ」というカラムを立てる方法が使われることも多いです。これは実際にテーブルからデータを削除する「物理削除」とは異なり、テーブルからデータを削除するのではなく、「削除済み」というマークをつける「論理削除」という方法です。これにより、「データは残っているけど、システム上では削除されたことになっている」という扱いになります。論理削除であれば、復活が容易ですが大量のデータを残すことでレスポンスが低下することもあるという可能性もあります。
過去のデータを参照する可能性があるものや削除することで影響する範囲が大きいデータにこの方法がよく用いられます。データを削除する場合は、削除フラグを利用することも考えましょう。
DELETE文とTRUNCATE文との違い
TRUNCATE文もDELETE文と同様に、データを削除するのに使われます。しかし、両者には相違点があります。
TRUNCATE TABLE テーブル名;
DELETE文は、1行ずつトランザクションログ(*)に記録しながらデータを削除するので、トランザクションの中で実行すれば、COMMITする前ならロールバックで戻すことができます。その分、大量のデータを削除する場合は時間がかかります。また、WHERE句でデータの一部だけを削除することもできます。
TRUNCATE文は、テーブルのデータを行単位ではなくまとめて削除するため、大量のデータでもすばやく動作します。ただし、WHERE句は使えず、データの一部のみを削除するということはできません。また、MySQLやOracleではTRUNCATE文を実行すると自動的に確定するため、BEGINのあとに実行してもROLLBACKで元に戻せません(PostgreSQLのTRUNCATEのように、トランザクション内なら戻せるデータベースもあります)。MySQLの仕様はMySQL公式リファレンスのTRUNCATE TABLEステートメント、自動的に確定する文の一覧は暗黙的なコミットを発生させるステートメントで確認できます。MySQLでは、AUTO_INCREMENTの連番も初期値に戻ります。
テーブルの中身ではなく、テーブルそのものを削除したい場合はDROP TABLE文を使います(MySQL公式リファレンスのDROP TABLEステートメント)。3つの違いをまとめると次のとおりです。
| 文 | 削除するもの | WHERE句 | ROLLBACK(MySQL) | テーブル |
| DELETE | 条件に合う行(省略時は全行) | 使える | 戻せる(トランザクション内) | 残る |
| TRUNCATE | 全行 | 使えない | 戻せない | 残る |
| DROP TABLE | テーブルそのもの | 使えない | 戻せない | なくなる |
トランザクションログ:データベースの変更履歴を記録したものでストレージ上のファイルとして記録される場合が多い。
SQLの勉強方法は?
書籍やインターネットで学習する方法があります。昨今では、YouTubeなどの動画サイトやエンジニアのコミュニティサイトなども充実していて多くの情報が手に入ります。
そして、より効率的に知識・スキルを習得するには、知識をつけながら実際に手を動かしてみるなど、インプットとアウトプットを繰り返していくことが重要です。特に独学の場合は、有識者に質問ができたりフィードバックをもらえるような環境があると、理解度が深まるでしょう。
ただ、SQLに限らず、ITスキルを身につける際、どうしても課題にぶつかってしまうことはありますよね。特に独学だと、わからない部分をプロに質問できる機会を確保しにくく、モチベーションが続きにくいという側面があります。独学でモチベーションを維持する自信がない人にはプログラミングスクールという手もあります。費用は掛かりますが、その分スキルを身につけやすいです。しっかりと知識・スキルを習得して実践に活かしたいという人はプログラミングスクールがおすすめです。
プログラミングスクールならテックマニアがおすすめ!
ITスキル需要の高まりとともにプログラミングスクールも増えました。しかし、どのスクールに通うべきか迷ってしまう人もいるでしょう。そんな方にはテックマニアをおすすめします!これまで多くのITエンジニアを育成・輩出してきたテックマニアでもプログラミングスクールを開講しています。
<テックマニアの特徴>
・たしかな育成実績と親身な教育 ~セカンドキャリアを全力支援~
・講師が現役エンジニア ~“本当”の開発ノウハウを直に学べる~
・専属講師が学習を徹底サポート ~「わからない」を徹底解決~
・実務ベースでスキルを習得 ~実践的な凝縮カリキュラム~
このような特徴を持つテックマニアはITエンジニアのスタートラインとして最適です。
話を聞きたい・詳しく知りたいという方はこちらからお気軽にお問い合わせください。
SQL関連記事
- RDBを操作するデータベース言語「SQL」とは?
- RDB以外のデータベース管理システム「NoSQL」とは?
- RDB管理システム「MySQL」とは?
- RDB管理システム「PostgreSQL」とは?
- RDB管理システム「SQL Server」とは?
- RDB管理システム「SQLite」とは?
- ブラウザ上でMySQLを管理できる「phpMyAdmin」とは?
- データを抽出する「SELECT」文
- データを追加する「INSERT」文
- データを削除する「DELETE」文
- データを更新する「UPDATE」文
- テーブル構造を変更する「ALTER TABLE」文
- 抽出条件を指定する「WHERE」句
- 抽出条件を指定する「HAVING」句
- 複数の抽出条件をまとめる「IN」句
- 重複レコードを除外する「DISTINCT」
- 抽出範囲を指定する「BETWEEN」演算子
- 抽出条件を満たすレコードの存在の有無を調べる「EXISTS」句
- レコード件数を取得する集計関数「COUNT」関数
- レコードをグループ化する「GROUP BY」句
- 抽出結果を並び替える「ORDER BY」句
- テーブル間のデータを結合する「JOIN」句
- 内部結合「INNER JOIN」句
- 抽出結果を統合して表示する「UNION」句
- データの曖昧検索「LIKE」句
- データの取得件数を制限する「LIMIT」句
- 条件分岐処理「CASE」式
- 「NULL」の扱い方
- 「主キー」とは?
- 「外部キー」とは?
- 2023.09.13
- Other
Author:テックマニア編集部 早川 投稿一覧
Otherカテゴリの最新記事
-
- 2026.10.09
Vercelとは?Webサイトをデプロイする方法を初心者向けに実践解説
-
- 2026.10.02
Homebrewとは?Macへのインストール方法・使い方をエンジニア目線で解説
-
- 2026.09.18
Postmanとは?初心者でもAPIリクエストが送れるようになる使い方ガイド
-
- 2026.09.18
Supabaseとは?できること・実際の使い方をエンジニア視点で解説
-
- 2026.07.03
Redashとは?メリットや特徴、ダッシュボードの作り方を詳しく解説
-
- 2026.06.26
Neovimとは【入門編】使い方・インストール手順を徹底解説
