2011-03-21 30 views
1

如何使用Django ORM表示這個簡單的SQL?Django自引用嵌套QuerySets

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

在這種情況下,警報表所發生的一切,對每個類別標籤的可能警告的歷史 - 並且查詢返回的最新警報爲每個類別。

回答

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個查詢,但他們應該是比子查詢的查詢效率更高。

+0

關於使用pk的好主意。 – Evgeny 2011-03-22 08:00:56

+1

它實際上只有一個單一的查詢與嵌套選擇。內部選擇是分組類別和類型的集合,這正是我在OP中要求做的。 SELECT * FROM alerts where ID IN( SELECT MAX(U0.id)AS maxid FROM alerts U0 GROUP BY U0。「category」,U0。「subtype」 ) – Evgeny 2011-03-22 08:13:02