クエリでレコードのページ番号を見つける必要があります。オフセットと制限がありますが、これを計算するには行番号も必要になります。
クエリオブジェクトとレコードIDが与えられた場合、行番号を見つけるにはどうすればよいですか?
行番号は、クエリテーブルを基準にする必要があります。制限とオフセットは後で適用されます。
助けていただければ幸いです...
クエリでレコードのページ番号を見つける必要があります。オフセットと制限がありますが、これを計算するには行番号も必要になります。
クエリオブジェクトとレコードIDが与えられた場合、行番号を見つけるにはどうすればよいですか?
行番号は、クエリテーブルを基準にする必要があります。制限とオフセットは後で適用されます。
助けていただければ幸いです...
レコードの「ページ番号」をそのように逆に取得するのは少し厄介です。通常、レコードの「詳細」から「それらすべてのページ付けされたビュー」に戻りたいシステムは、 「詳細」ページへのページ番号。
しかし、有能なデータベースで作業していると仮定すると、ウィンドウ関数を使用して任意の SELECT ステートメントから行番号を取得できます。これは、Postgresql、SQL Server、または Oracle (特に MySQL や SQLite ではない) などの DB で取得できます。
PG を使用して、いくつかのデータから始めることができます。
test=> create table data(id SERIAL primary key, value varchar(20));
NOTICE: CREATE TABLE will create implicit sequence "data_id_seq" for serial column "data.id"
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "data_pkey" for table "data"
CREATE TABLE
test=> insert into data (value) values ('d1'), ('d2'), ('d3'), ('d4'), ('d5'), ('d6'), ('d7'), ('d8'), ('d9'), ('d10'), ('d11'), ('d12'), ('d13'), ('d14'), ('d15'), ('d16');
INSERT 0 16
次に、このデータを選択し、row_number()
ウィンドウ関数を使用して整数の行数を取得できます。
test=> select value, row_number() over (order by id) as rownum from data;
value | rownum
-------+--------
d1 | 1
d2 | 2
d3 | 3
d4 | 4
d5 | 5
d6 | 6
d7 | 7
d8 | 8
d9 | 9
d10 | 10
d11 | 11
d12 | 12
d13 | 13
d14 | 14
d15 | 15
d16 | 16
(16 rows)
サブクエリ内でウィンドウ処理されたデータを適用すると、このカウントに基づいて結果のスライスを選択できます。
test=> select value from (select value, row_number()
> over (order by id) as rownum from data) as sub where rownum between 5 and 10;
value
-------
d5
d6
d7
d8
d9
d10
(6 rows)
したがって、レコードが「d14」でページサイズが 5 の場合、次のようにすることができます。
test=> select (rownum - 1) / 5 from (select value, row_number()
> over (order by id) as rownum from data) as sub where value='d14';
?column?
----------
2
(1 row)
SQLAlchemy はover()メソッド/関数を介してウィンドウ関数を提供するため、これに対する典型的な ORM マッピングを想定した SQLA クエリは次のようになります。
subq = session.query(
Data.value,
func.row_number().over(order_by=Data.id).label('rownum')
).subquery()
pagenum = session.query((subq.c.rownum - 1) / 5).\
filter(subq.c.value == 'd14').scalar()
ページネーションにウィンドウ関数と制限/オフセットを使用する限り、さまざまな方法のパフォーマンスを比較するためにここに書いた比較と、私が時々使用するウィンドウ化された範囲クエリのレシピをチェックする価値があります。
私は長く懸命に探してきましたが、6時間後に解決策を見つけました。
私は Mysql を使用しているので、これを行う唯一の方法は @ 変数を使用することだと思います。
これをSQLAlchemyに実装する方法は次のとおりです。
qry = ...
sel = select([qry.c.id, "@rownum := @rownum + 1 as rownumber"])
conn = sel.engine.connect()
conn.execute("SET @rownum:=0")
res = conn.execute(sel)
@rownum
行ごとに増加します。qry
必要に応じて、2 行目 からさらに列を追加できます。リストを返すために呼び出すことができる列res
を持つ最終的なテーブルですrownumber
res.fetchall()