LIMIT / OFFSET
| 対応: | MySQL 拡張 |
|---|
取得する行数と開始位置を指定する句です。ページネーション(ページ送り)の実装などに使用します。
構文
取得件数を制限します(MySQL・PostgreSQL・SQLiteなど)。
SELECT 列名 FROM テーブル名 LIMIT 件数;
開始位置と件数を指定します(OFFSET は 0 始まり)。
SELECT 列名 FROM テーブル名 LIMIT 件数 OFFSET 開始位置;
MySQL独自の短縮構文です(LIMIT 開始位置, 件数)。
SELECT 列名 FROM テーブル名 LIMIT 開始位置, 件数;
構文一覧
| 構文 | 概要 |
|---|---|
| LIMIT 件数 | 取得する最大行数を指定します。MySQL・PostgreSQL・SQLiteで使用できます。 |
| OFFSET 開始位置 | 取得を開始する行の位置を指定します。0が先頭です。LIMIT と組み合わせて使用します。 |
| LIMIT 開始位置, 件数 | MySQLの短縮構文です。LIMIT 0, 10 は先頭から10件を意味します。 |
| FETCH FIRST 件数 ROWS ONLY | 標準SQL(SQL:2008以降)の構文です。Oracle・DB2・PostgreSQLなどで使用できます。 |
サンプルコード
以下の『employees』テーブルを例に説明します。
給与が高い順に上位3件の社員を取得します。
sample_limit_offset.sql
SELECT name, salary FROM employees ORDER BY salary DESC LIMIT 3;
+----------+--------+ | name | salary | +----------+--------+ | 桐生一馬 | 380000 | | 真島吾朗 | 350000 | | 秋山駿 | 320000 | +----------+--------+ 3 rows in set
ページネーションの例(1ページ3件、2ページ目を取得します)。
sample_limit_offset.sql
SELECT name, hire_date FROM employees ORDER BY hire_date DESC LIMIT 3 OFFSET 3;
+----------+------------+ | name | hire_date | +----------+------------+ | 錦山彰 | 2022-01-10 | | 秋山駿 | 2021-04-01 | +----------+------------+ 2 rows in set
MySQL短縮構文での同じ処理です。
sample_limit_offset.sql
SELECT name, hire_date FROM employees ORDER BY hire_date DESC LIMIT 3, 3;
+----------+------------+ | name | hire_date | +----------+------------+ | 錦山彰 | 2022-01-10 | | 秋山駿 | 2021-04-01 | +----------+------------+ 2 rows in set
入社が最も古い社員1名を取得します。
sample_limit_offset.sql
SELECT name, hire_date FROM employees ORDER BY hire_date ASC LIMIT 1;
+----------+------------+ | name | hire_date | +----------+------------+ | 桐生一馬 | 2019-09-15 | +----------+------------+ 1 row in set
データベース別の書き方
PostgreSQL・SQLite は MySQL と同じ『LIMIT / OFFSET』が使用できます。
SELECT name, salary FROM employees ORDER BY salary DESC LIMIT 3 OFFSET 3;
Oracle は『FETCH FIRST』を使用します(12c以降)。
SELECT name, salary FROM employees ORDER BY salary DESC OFFSET 3 ROWS FETCH NEXT 3 ROWS ONLY;
概要
『LIMIT』と『OFFSET』はページネーション実装に欠かせない機能です。ページ番号($page)と1ページあたりの件数($per_page)から、OFFSETは『($page - 1) * $per_page』で計算できます。
『ORDER BY』なしで『LIMIT / OFFSET』を使用すると、取得順序が保証されません。ページネーションでは必ず『ORDER BY』で並び順を固定してから使用してください。
データが大量にある場合、OFFSETの値が大きくなるほどパフォーマンスが低下します。大規模データではカーソルベースのページネーション(直前のIDを条件にする方法)の採用を検討してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。