получение одной дочерней строки на основе максимального значения с использованием Django ORM

StackOverflow https://stackoverflow.com/questions/931730

Вопрос

У меня есть модель «Рынок», которая имеет отношение «один ко многим» к другой модели «Контракт»:

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

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

Я хотел бы получить объекты Market вместе с контрактом с максимальной ценой каждого из них.Вот как я бы это сделал с помощью необработанного SQL:

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

Есть ли способ реализовать это без использования SQL?Если есть, то какой из них следует предпочесть с точки зрения производительности?

Это было полезно?

Решение

В Django 1.1 (в настоящее время бета-версия) добавлены агрегирование поддержка API базы данных.Ваш запрос можно выполнить следующим образом:

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

При этом генерируется следующий 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)

API использует дополнительное соединение вместо подзапроса (как это делает ваш запрос).Трудно сказать, какой запрос выполняется быстрее, особенно не зная системы базы данных.Я предлагаю вам провести несколько тестов и принять решение.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top