Question

J'ai un modèle, « marché » qui a une relation un à plusieurs à un autre modèle, « Contrat »:

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

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

Je voudrais aller chercher des objets du marché ainsi que le contrat avec le prix maximum de chacun. Voilà comment je le ferais via SQL brut:

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

Y at-il un moyen de mettre en œuvre ce sans utiliser SQL? S'il y a, que l'on devrait être préféré en termes de performance?

Était-ce utile?

La solution

Django 1.1 (actuellement bêta) ajoute agrégation soutien au API de base de données. Votre requête peut être fait comme ceci:

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

Cela génère la requête SQL suivante:

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)

L'API utilise une somme supplémentaire de se joindre au lieu d'une sous-requête (comme votre requête ne). Il est difficile de dire quelle requête est plus rapide, en particulier sans connaître le système de base de données. Je vous suggère de faire quelques points de repère et de décider.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top