gpt4 book ai didi

django - 如何在 Django 中使用子查询?

转载 作者:行者123 更新时间:2023-11-29 11:10:01 25 4
gpt4 key购买 nike

我想获取每个客户的最新购买 list ,按日期排序。

除了日期之外,以下查询执行我想要的操作:

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

由于 DISTINCT ON,我不得不使用 customer_id 作为第一个 ORDER BY 表达式。

我想按日期排序,所以我真正需要的查询应该是这样的:

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 来实现此结果的方法。

最佳答案

这可能不是您要找的东西,但它可能会让您更接近。看看Django's annotate .

下面是一个可能有用的例子:

  from django.db.models import Max
Customer.objects.all().annotate(most_recent_purchase=Max('purchase__date'))

这将为您提供一份客户模型列表,其中每个模型都有一个名为“most_recent_purchase”的新属性,并将包含他们上次购买的日期。生成的 sql 如下所示:

SELECT "demo_customer"."id", 
"demo_customer"."user_id",
MAX("demo_purchase"."date") AS "most_recent_purchase"
FROM "demo_customer"
LEFT OUTER JOIN "demo_purchase" ON ("demo_customer"."id" = "demo_purchase"."customer_id")
GROUP BY "demo_customer"."id",
"demo_customer"."user_id"

另一种选择是向您的客户模型添加一个如下所示的属性:

  @property
def latest_purchase(self):
return self.purchase_set.order_by('-date')[0]

您显然需要处理此属性中没有任何购买的情况,这可能不会很好地执行(因为您将为每个客户运行一个查询以获取他们的最新购买)。

我过去使用过这两种技术,它们在不同情况下都表现良好。我希望这有帮助。祝你好运!

关于django - 如何在 Django 中使用子查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14331224/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com