概要
SELECT した時の最初から何行目まで削除したい、といった場合の方法。
サブクエリを利用して順番を指定する。
実行例 (シンプルな例)
| id | name | quantity |
|---|---|---|
| 1 | tomato | 100 |
| 2 | potato | 120 |
| 3 | pumpkin | 50 |
上記のようなテーブルで「quantity」の値が一番小さいレコードを削除したいという場合、
以下のようなSQLとなる。
(集計関数の min()を使う方法もあるが
今回はORDER BYを使用する)
ポイントとしては
-
サブクエリでは必ず
ORDER BYを指定する - 出来る限り PRIMARY KEY やUNIQUEなカラムを WHERE 句で指定する
- WHERE 句で指定するカラムとサブクエリで取得するカラムの数と型を揃える
DELETE FROM product
WHERE
id = (
SELECT
id
FROM
product
ORDER BY
quantity
LIMIT 1
)
;
| id | name | quantity |
|---|---|---|
| 1 | tomato | 100 |
| 2 | potato | 120 |
実行例 (範囲を指定する)
何番目~何番目を指定する場合はサブクエリで
LIMITとOFFSETを指定すればいい。
何番目だけ、としたい場合はLIMITを1にしてやればいい。
| name | quantity | insert_date |
|---|---|---|
| tomato | 100 | 2021-04-02 |
| potato | 120 | 2021-04-03 |
| pumpkin | 50 | 2021-04-02 |
| tomato | 50 | 2021-04-02 |
| pumpkin | 30 | 2021-04-01 |
上記のようなテーブルから「insert_date」「quantity」「name」の順番でソートした結果から
2番目〜4番目に古い(2番目から3件の)レコードを削除する場合、以下のようなSQLとなる。
ポイントとしては
-
サブクエリでは必ず
ORDER BYを指定する -
WHERE ~ INを利用する -
キーになるカラムがない場合、ユニークになる条件を満たすカラムを
WHEREに指定する -
WHEREで指定するカラムとサブクエリで取得するカラムの数と型を揃える
DELETE FROM product
WHERE (
name
, quantity
, insert_date
) in (
SELECT
name
, quantity
, insert_date
FROM
product
ORDER BY
insert_date
, quantity
, name
LIMIT 3
OFFSET 1
)
;
| name | quantity | insert_date |
|---|---|---|
| potato | 120 | 2021-04-03 |
| pumpkin | 30 | 2021-04-01 |
サブクエリを使わない方法がある?
公式のドキュメントには、サブクエリを使わずに DELETE 文にそのまま
ORDER BY、LIMIT、OFFSET 句をつけて実行する方法が記載されている。
ただしこれはデフォルトでは利用できず、SQLITE_ENABLE_UPDATE_DELETE_LIMITオプションを指定して
ソースコードからコンパイルしなおさなければならない。
Optional LIMIT and ORDER BY clauses
参考サイト
-
SQLite 公式サイト(英語)
https://www.sqlite.org/index.html -
SQLite Query Language: DELETE(英語)
公式のDELETE構文に関するドキュメント
https://www.sqlite.org/lang_delete.html -
The LIMIT clause
公式のLIMIT, OFFSETに関するドキュメント
https://www.sqlite.org/lang_select.html#the_limit_clause