8

私は古典的なページネーションシステムを使用してLIMIT startrecord, endrecordおり、Xレコードがどのページ番号にあるかを把握したいと考えています。

私が今持っている唯一のアイデアは、それを見つけるためにすべてのレコードを再帰的に探すことです。しかし、私はもっと「経済的な」方法を探しています!

何か案は ?

4

5 に答える 5

4

探しているレコードの前にあるレコードの数を数えます。これには、自然なクエリの順序を想定する必要があります。

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_fieldMySQL が主キーを使用するレコードと同じ値を持つレコードであり、この場合はid. そして、それがOR私たちが私たちの状態にその部分を持っている理由です. 私の答えでは、元のクエリ ( limit ステートメントを含む) を昇順で並べ替えていると想定していますが、降順で並べ替えている場合は、すべてをに変更する必要があり<ます>

于 2014-01-19T00:55:27.043 に答える
3

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 が何であれ、それらが返される順序が同じままである限り。

于 2014-01-22T12:31:48.983 に答える
-1

「経済的な」方法を実際に作成することはできません。MySQL からレコードの位置を知る方法がないため、DB からレコードの完全なリストを取得する必要があります。

並べ替え、データが変更される頻度に応じて、レコードに列内の位置を割り当てることができます。クエリを実行しているテーブルに列の位置を追加します。それはすべての場合に実現可能ではないかもしれません。

于 2014-01-21T18:32:28.877 に答える