PostgreSQL をデータベースのバックエンドとして使用していて、データベース間の互換性が必要ない場合は、次のようなことを可能にする強力なウィンドウ関数を使用できます。
あなたのテーブルがそのように見えると想像してください:
CREATE TABLE x (
i serial primary key,
value integer not null,
date timestamp,
category text);
そして、各カテゴリの最新の値が必要です。あなたは〜をします :
SELECT
first_value(i) over w,
first_value(value) over w,
first_value(date) over w
category,
FROM x
WINDOW w AS (PARTITION BY category ORDER BY date DESC);
raw
クエリ セット マネージャーのメソッドを使用して、django でこのようなクエリを使用できます。
ModelX.objects.raw("""SELECT DISTINCT ....... FROM x WINDOW w .....""")
カテゴリごとに最後の N エントリを取得するには、クエリがもう少し複雑になり、サブクエリが必要になります。
SELECT i, value, date, category
FROM (SELECT
i, value, date, category,
row_number() over w
FROM x
WINDOW w AS (PARTITION BY category ORDER BY date DESC)) AS subquery
WHERE subquery.row_number <= 30;
それを見て、ビューを作成することさえできます:
CREATE VIEW x_with_reverse_date_index AS
(SELECT
i, value, date, category,
row_number() over w
FROM x
WINDOW w AS (PARTITION BY category ORDER BY date DESC));
そして、このビューをクエリする django モデルを作成します:
class ModelX(models.Model):
...
...
row_number = models.IntegerField("Row number when ordering by date desc")
class Meta:
db_table = 'x_with_reverse_date_index'
そしてそれを「普通に」照会します:
ModelX.objects.filter(category__in = ('catA','catB'), row_number__lte = 30)
ModelX.objects.filter(row_number = 29)
...
警告: 繰り返しますが、別のデータベース エンジンで動作するコードが必要な場合は、これを行わないでください。