Pregunta

Tengo un modelo de "mercado" que tiene una relación de uno a muchos a otro modelo, "Contrato":

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

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

Me gustaría ir a buscar objetos de mercado a lo largo de con el contrato con el precio máximo de cada uno. Esta es la forma en que lo haría a través de SQL prima:

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

¿Hay una manera de implementar esto sin usar SQL? Si existe, ¿cuál debería ser preferible en términos de rendimiento?

¿Fue útil?

Solución

Django 1.1 (actualmente beta) añade agregación apoyo a la API de base de datos. Su consulta se puede hacer así:

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

Esto genera la siguiente 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)

La API utiliza un extra se unen en lugar de una subconsulta (como su consulta lo hace). Es difícil decir cuál consulta es más rápido, especialmente sin conocer el sistema de base de datos. Le sugiero que haga algunos puntos de referencia y decidir.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top