【问题标题】:An alternative query to postgres' distinct in Djangopostgres 在 Django 中的 distinct 的替代查询
【发布时间】:2018-08-23 17:19:45
【问题描述】:

鉴于这个 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 中,所以我一直在寻找模拟它的查询。我已经编写/找到了一个可以完成这项工作的查询:

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 的 db-agnostic 方式执行此操作。

【问题讨论】:

    标签: sql django postgresql django-models django-orm


    【解决方案1】:

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

    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 查询集...我的大脑此刻想不出任何东西 :)

    【讨论】:

    • 在这种情况下它来自哪个“方面”并不重要,所以这是一个很好的解决方案。
    • 好的,太好了!我进行了快速编辑,因为您只需要子查询中的第一个值
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-21
    • 1970-01-01
    • 2011-09-29
    • 2018-10-19
    • 2021-10-22
    • 2012-06-29
    相关资源
    最近更新 更多