2011-03-21 4 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 그냥 타임 스탬프, 생성 된 이후 같다고 가정

  • :

    여기에 한 가지 제안입니다. 그래서 cols를 categorytype으로 그룹화 한 다음 MAX ('timestamp') 대신 MAX ('pk')를 선택합니다.

    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

+1

실제로 중첩 된 선택이있는 단일 쿼리 만 수행합니다. 내부 선택은 그룹화 된 카테고리 및 유형에 대한 집계이며, 이는 OP에서 요청한 것과 정확히 일치합니다. SELECT * 경고 FROM WHERE ( 을 경고 U0 U0 BY GROUP. "카테고리", U0. "하위"FROM maxid AS SELECT MAX (U0.id)) 아이디 IN – Evgeny