2009-05-31 2 views
3

를 사용하여 최대 값을 기준으로 하나의 자식 행을 가져 오는 계약과 함께 시장 객체를 최대 가격으로 가져 오는 것을 좋아합니다. 이것은 원시 SQL을 통해 수행하는 방법입니다.내가 다른 모델에 일대 다 관계를 가지고있는 모델 "시장"이 "계약"장고 ORM

SELECT M.id as market_id, M.name as market_name, C.name as contract_name, C.price 
as price from pm_core_market M INNER JOIN 
    (SELECT market_id, id, name, MAX(current_price) as price 
     FROM pm_core_contract GROUP BY market_id) AS C 
ON M.id = C.market_id 

SQL을 사용하지 않고이를 구현할 수있는 방법이 있습니까? 있다면, 어느 것이 성능 측면에서 선호되어야 하는가?

답변

9

Django 1.1 (현재 베타)은 aggregation 지원을 데이터베이스 API에 추가합니다. 귀하의 질의는 다음과 같이 수행 할 수 있습니다

from django.db.models import Max, F 

Contract.objects.annotate(max_price=Max('market__contract__current_price')).filter(current_price=F('max_price')).select_related() 

이 다음과 같은 SQL 쿼리를 생성

SELECT contract.id, contract.name, contract.market_id, contract.current_price, MAX(T3.current_price) AS max_price, market.id, market.name 
FROM contract LEFT OUTER JOIN market ON (contract.market_id = market.id) LEFT OUTER JOIN contract T3 ON (market.id = T3.market_id) 
GROUP BY contract.id, contract.name, contract.market_id, contract.current_price, market.id, market.name 
HAVING contract.current_price = MAX(T3.current_price) 

API는 추가가 (쿼리가하는 것처럼) 대신 하위 쿼리의 조인 사용합니다. 특히 데이터베이스 시스템을 모른 채로 어떤 쿼리가 더 빠르는지 알기가 어렵습니다. 나는 당신이 어떤 벤치 마크를하고 결정할 것을 제안한다.

+0

하위 쿼리가 두 개 이상의 JOIN보다 효율적이라고 가정 했겠지 만 그 가정을 가정해서는 안됩니다. 그것을 벤치마킹하고보십시오. –

+0

아이 만, 감사합니다! 장고 초보자로서 그것은 작동하는데 시간이 좀 걸렸습니다 :) 저는 성명서에 필터에 관한 질문이 있습니다. 하나 이상의 계약 가격이 동등한 - 가능성없는 사건에 대한 가능성이 있습니다. 그렇다면 쿼리는 모든 것을 가져 와서 여러 시장 계약을 맺습니다. 맞습니까? – shanyu

+0

@ozgur - 실제로 두 계약이 동일한 가격 (최대가 될 수도 있음) 인 경우 두 계약이 모두 반환됩니다. –