Pergunta

Eu tenho um modelo, "Mercado", que tem uma relação de um-para-muitos para outro modelo, "Contrato":

class Market(models.Model):
    name = ...
    ...

class Contract(models.Model):
    name= ...
    market = models.ForeignKey(Market, ...)
    current_price = ...

Eu gostaria de buscar objetos mercado, juntamente com o contrato com o preço máximo de cada um. Isto é como eu faria isso via SQL cru:

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

Existe uma maneira de implementar isso sem usar SQL? Se houver, qual deve ser preferido em termos de desempenho?

Foi útil?

Solução

Django 1.1 (atualmente beta) adiciona agregação apoio ao API de banco de dados. Sua consulta pode ser feito assim:

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()

Isso gera a seguinte consulta 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)

A API usa um extra de associação em vez de uma subconsulta (como sua consulta faz). É difícil dizer qual consulta é mais rápido, especialmente sem saber o sistema de banco de dados. Eu sugiro que você faça algumas referências e decidir.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top