Django自引用嵌套的QuerySet

时间:2011-03-21 21:59:42

标签: django django-models django-orm

如何使用Django ORM表示这个简单的SQL?

SELECT * FROM alerts a1 WHERE timestamp = (
    SELECT MAX(timestamp) FROM alerts a2
        WHERE a1.category = a2.category
        AND   a1.type     = a2.type
)

在这种情况下,警报表是发生的所有可能警报的历史记录,每个警报都有一个类别标记 - 并且查询会返回每个类别的最新警报。

1 个答案:

答案 0 :(得分:1)

看起来没有办法将您的查询直接翻译成django-orm。您将需要使用原始查询,或搜索不同的解决方案。

这是一个可能的主张:

  • 我假设pk就像时间戳,后者创建 - 更高。因此,我按categorytype对cols进行分组,然后选择MAX('pk')而不是MAX('timestamp')。

    latest_events_pks = Event.objects.values('category', 'typ') \
                                     .annotate(max=Max('pk')) \
                                     .values_list('max', flat=True)
    

    它会生成如下查询:

    SELECT MAX("event"."id") AS "max" FROM "event" 
    GROUP BY "event"."category", "event"."typ"
    
  • values_list()返回了一个id列表,例如:[1, 15, 20, 22]。因此可以选择适当的事件:

    Event.objects.filter(id__in=latest_events_pks)
    

这是2个查询,但它们应该比带有子查询的查询更有效。