SQLite:上から何番目の行を削除したい
はじめに
最近、大学でSQLiteを習ったのですが、データベースを作成中「上から〇番目のものを消したいな」と思ったのですが、それが上手くいかなかったのでいろいろと調べてみました。
使うテーブル
テーブル名:user
id | name |
---|---|
2 | tanaka |
5 | kato |
7 | maeda |
LIMITとOFFSET
SELECT文ではLIMITとOFFSETという変数を指定するだけで、上から何番目の行を指定することができます。
LIMIT
limit
というのは抜き出した行(またはパラメータ)の数を制限する命令です。
たとえば
SELECT * FROM user LIMIT 2;
としたときの結果は以下の表になります。
id | name |
---|---|
2 | tanaka |
5 | kato |
OFFSET
OFFSET
というのは行を取得するときの開始位置を決める命令です。
LIMIT
を使用しているときのみ使用可能です。
たとえば
SELECT * FROM user OFFSET 1;
と書くとエラーを吐きます。
実際に使用するときは
SELECT * FROM user LIMIT 2 OFFSET 1;
と書きます。その結果は以下の表になります。
id | name |
---|---|
5 | kato |
7 | maeda |
上からk番目を取得したいとき
以上のことを踏まえると上からk番目を取得する書き方は以下のようになります。
SELECT * FROM user LIMIT 1 OFFSET k-1;
上からk番目を削除したい
これをDELETE文でもできないかと思い以下のようなコマンドを書きました。
DELETE FROM user LIMIT 1 OFFSET k-1;
しかし、このコードはエラーを吐いてしまいました……。 どうしてかと思い調べてみるとこんな図がありました。
SQLite Syntax: delete-stmt-limitedより引用
つまりはDELETE文ではLIMIT
もOFFSET
も使えないらしいです。
SELECT文と組み合わせる
じゃあ、上からk番目を消すことができないのかというと別にそういうわけではなく、SELECT文と組み合わせると可能になるようです。
delete from user where id = (select id from user limit 1 offset k-1);
(select id from user limit 1 offset k-1)
は上からk番目の行のidを取得しています。そのidと同じ行を削除すれば結果的に上からk番目の行を削除できるというわけです。
おわりに
今回はDELETE文でスマートに上からk番目を削除したかったのですが、どうやら仕組み的に間接的な方法しかないことが分かりました。 ただ正直、遠回りな分コマンドが長くなってしまうのはあまり好きではないですね……。