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?

War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top