【问题标题】:Django self-referencing nested QuerySetsDjango 自引用嵌套查询集
【发布时间】:2011-03-21 21:59:41
【问题描述】:

如何使用 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
)

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

【问题讨论】:

    标签: django django-models django-orm


    【解决方案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 个查询,但它们应该比带有子查询的查询更有效。

    【讨论】:

    • 关于使用 pk 的好主意。
    • 它实际上只执行一个带有嵌套选择的查询。内部选择是分组类别和类型的聚合,这正是我在 OP 中要求做的。 SELECT * FROM alerts WHERE id IN (SELECT MAX(U0.id) AS maxid FROM alerts U0 GROUP BY U0."category", U0."subtype")
    猜你喜欢
    • 2011-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-29
    • 2013-11-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多