私は古典的なページネーションシステムを使用してLIMIT startrecord, endrecord
おり、Xレコードがどのページ番号にあるかを把握したいと考えています。
私が今持っている唯一のアイデアは、それを見つけるためにすべてのレコードを再帰的に探すことです。しかし、私はもっと「経済的な」方法を探しています!
何か案は ?
私は古典的なページネーションシステムを使用してLIMIT startrecord, endrecord
おり、Xレコードがどのページ番号にあるかを把握したいと考えています。
私が今持っている唯一のアイデアは、それを見つけるためにすべてのレコードを再帰的に探すことです。しかし、私はもっと「経済的な」方法を探しています!
何か案は ?
探しているレコードの前にあるレコードの数を数えます。これには、自然なクエリの順序を想定する必要があります。
SELECT COUNT(id) AS c
FROM tbl
WHERE sort_field < ((SELECT sort_field FROM tbl WHERE id = 18))
OR (sort_field = ((SELECT sort_field FROM tbl WHERE id = 18)) AND id < 18);
次に、 を取得しc
て計算しceilling(c/page_size)
ます。これにより、レコードが含まれるページ番号が得られます。覚えておくべき唯一の重要なことは、制限付きのクエリで行うのと同じ順序でレコードを並べ替える必要があるということです。
クエリの動作を説明するために、ID 18 のレコードの前にあるレコードの数をカウントします。唯一のトリッキーな部分は、sort_field
MySQL が主キーを使用するレコードと同じ値を持つレコードであり、この場合はid
. そして、それがOR
私たちが私たちの状態にその部分を持っている理由です. 私の答えでは、元のクエリ ( limit ステートメントを含む) を昇順で並べ替えていると想定していますが、降順で並べ替えている場合は、すべてをに変更する必要があり<
ます>
。
s
副選択の一部としてクエリでこのようなものを使用します
SELECT s.row, s.RECORD, YOUR_OTHER_FIELDS...
FROM (SELECT @row := 0) cnt
JOIN (SELECT @row := @row + 1 row, RECORD, ...YOUR QUERY WITH ORDER BY ...) s
WHERE s.RECORD = <desired record number>
ページネーションのページサイズで行を分割します。具体的だが無意味な例:
SELECT p.row, p.id
FROM (SELECT @row := 0) cnt
JOIN (SELECT @row := @row + 1 row, id FROM products ORDER BY id desc) p
WHERE p.id = 485166
意図したとおり、row
副選択で使用する順序によって値が変わります。
変数の初期化をクエリに組み込むため、これは 1 つのステートメントにすぎません。また、行の自然な順序や分布にも依存しません。指定した (または除外した) ORDER が何であれ、それらが返される順序が同じままである限り。
「経済的な」方法を実際に作成することはできません。MySQL からレコードの位置を知る方法がないため、DB からレコードの完全なリストを取得する必要があります。
並べ替え、データが変更される頻度に応じて、レコードに列内の位置を割り当てることができます。クエリを実行しているテーブルに列の位置を追加します。それはすべての場合に実現可能ではないかもしれません。