Abrufen Reihe einzelner Kind basierend auf einem Maximalwert unter Verwendung Django ORM
-
06-09-2019 - |
Frage
Ich habe ein Modell, „Markt“, die eine Eins-zu-viele-Beziehung zu einem anderen Modell hat, „Vertrag“:
class Market(models.Model):
name = ...
...
class Contract(models.Model):
name= ...
market = models.ForeignKey(Market, ...)
current_price = ...
Ich mag Markt Objekte zusammen mit dem Vertrag mit dem Höchstpreis von jedem holen. Dies ist, wie ich es über rohen SQL tun würde:
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
Gibt es eine Möglichkeit, diese SQL ohne zu implementieren? Wenn es, die man in Bezug auf Leistung bevorzugt werden soll?
Lösung
Django 1.1 (derzeit Beta) fügt Aggregation Unterstützung der Datenbank-API. Ihre Anfrage kann wie folgt ausgeführt werden:
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()
Dies erzeugt die folgende SQL-Abfrage:
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)
Die API verwendet eine zusätzliche anstelle einer Unterabfrage kommen (wie Ihre Abfrage der Fall ist). Es ist schwer zu sagen, welche Abfrage schneller, vor allem ohne das Datenbanksystem zu kennen. Ich schlage vor, dass Sie einige Benchmarks zu tun und entscheiden.