Как использовать подзапрос в Django?
Я хочу получить список последних покупок каждого клиента, отсортированный по дате.
Следующий запрос делает то, что я хочу, кроме даты:
(Purchase.objects
.all()
.distinct('customer')
.order_by('customer', '-date'))
Это производит запрос как:
SELECT DISTINCT ON
"shop_purchase.customer_id"
"shop_purchase.id"
"shop_purchase.date"
FROM "shop_purchase"
ORDER BY "shop_purchase.customer_id" ASC,
"shop_purchase.date" DESC;
Я вынужден использоватьcustomer_id
как первыйORDER BY
выражение из-заDISTINCT ON
.
Я хочу отсортировать по дате, поэтому запрос, который мне действительно нужен, должен выглядеть следующим образом:
SELECT * FROM (
SELECT DISTINCT ON
"shop_purchase.customer_id"
"shop_purchase.id"
"shop_purchase.date"
FROM "shop_purchase"
ORDER BY "shop_purchase.customer_id" ASC,
"shop_purchase.date" DESC;
)
AS result
ORDER BY date DESC;
Я не хочу сортировать с использованием Python, потому что я все еще должен ограничить страницу запроса. В базе данных может быть десятки тысяч строк.
Фактически, в настоящее время он сортируется в python и вызывает очень длительное время загрузки страницы, поэтому я пытаюсь это исправить.
В основном я хочу что-то вроде этогоhttps://stackoverflow.com/a/9796104/242969, Можно ли выразить это с помощью наборов запросов django вместо написания необработанного SQL?
Реальные модели и методы имеют длину в несколько страниц, но вот набор моделей, требуемых для набора запросов выше.
class Customer(models.Model):
user = models.OneToOneField(User)
class Purchase(models.Model):
customer = models.ForeignKey(Customer)
date = models.DateField(auto_now_add=True)
item = models.CharField(max_length=255)
Если у меня есть данные, такие как:
Customer A -
Purchase(item=Chair, date=January),
Purchase(item=Table, date=February)
Customer B -
Purchase(item=Speakers, date=January),
Purchase(item=Monitor, date=May)
Customer C -
Purchase(item=Laptop, date=March),
Purchase(item=Printer, date=April)
Я хочу иметь возможность извлечь следующее:
Purchase(item=Monitor, date=May)
Purchase(item=Printer, date=April)
Purchase(item=Table, date=February)
На каждого покупателя в списке входит не более одной покупки. Покупка является последней покупкой каждого клиента. Отсортировано по последней дате.
Этот запрос сможет извлечь, что:
SELECT * FROM (
SELECT DISTINCT ON
"shop_purchase.customer_id"
"shop_purchase.id"
"shop_purchase.date"
FROM "shop_purchase"
ORDER BY "shop_purchase.customer_id" ASC,
"shop_purchase.date" DESC;
)
AS result
ORDER BY date DESC;
Я пытаюсь найти способ не использовать сырой SQL для достижения этого результата.