Django 中 postgres 的另一种查询

An alternative query to postgres' distinct in Django

给定这个 django 模型:

def Price(model.Model):
    date = models.DateTimeField()
    item = models.ForeignKey('Item', on_delete=models.CASCADE)
    price = models.IntegerField(blank=True, null=True)

目标是获取每件商品的最新价格,可以非常简单地查询。假设 orm 使用的是 postgresql:

Price.objects.all().order_by('date').distinct('item')

使用其他数据库引擎时,无法 distinct on 特定字段,我想避免将自己锁定在 postgres 中,因此我一直在寻找模拟它的查询。我有 written/found 一个可以完成这项工作的查询:

Price.objects.raw('''
    SELECT P1.*
    FROM `merchapi_pricelog` P1
        LEFT JOIN `merchapi_pricelog` P2
            ON P1.item_id = P2.item_id AND P1.date < P2.date
    WHERE P2.date is NULL
''')

原始查询比在代码中加载和过滤数据要快,但我很想看看是否有更好的方法以与数据库无关的方式执行此操作,而不是使用原始查询 sql.

您可以使用子查询对其进行注释,因此可以在 Item 查询集中访问它。它有点 vice-versa,因为您似乎想要一个包含此数据的价格查询集,但这仍然适用于您:

latest_price = Price.objects.filter(pk=OuterRef('id')).order_by('-date').values('price')[:1]
items = Item.objects.annotate(latest_price=Subquery(latest_price))

我没有测试该代码,只是借用和修改了我在另一个项目中的类似代码,但相信它是准确的。

如果您需要遍历 Price 查询集,而不是 Item 查询集...我的大脑现在想不出任何东西:)