如何在 django 中执行“greatest-n-per-group”查询?

Posted

技术标签:

【中文标题】如何在 django 中执行“greatest-n-per-group”查询?【英文标题】:How can a do a "greatest-n-per-group" query in django? 【发布时间】:2011-01-07 20:51:57 【问题描述】:

(这是SQL join: selecting the last records in a one-to-many relationship的线程的django版本)

假设我有一张客户表和一张采购表。每次购买都属于一位客户。我想获得所有客户的列表以及他们最后一次购买。可以在没有原始 SQL 和多个数据库查询的情况下完成吗?

【问题讨论】:

Django Query That Get Most Recent Objects From Different Categories的可能重复 【参考方案1】:

您不能在 Django 中的一个查询中执行此操作。您可以通过客户最近一次购买的日期来获取客户,如下所示:

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

但您不会通过这种方式自动获得实际购买的权限。

【讨论】:

在 Django 2 和 3 中,此限制已被取消。请参阅已接受答案中的链接。【参考方案2】:

你可以看看类似的讨论:

Django Query That Get Most Recent Objects From Different Categories

【讨论】:

事实上,这是那个问题的重复。【参考方案3】:
SELECT  *
FROM    customers с
LEFT JOIN
        purchases p
ON      p.id = 
        (
        SELECT  id
        FROM    purchases pl
        WHERE   pl.customer = c.id
        ORDER BY
                pl.customer DESC, pl.date DESC
        LIMIT 1
        )

如果您的表是InnoDB,请确保您在purchases (customer, date) 上有一个复合索引,如果您的表是MyISAM,请确保在purchases (customer, date, id) 上有一个复合索引。

【讨论】:

为什么我们在 InnoDB 的索引中不需要 id? @netvope:因为InnoDB 是索引组织的,并且在每个索引中隐式包含PRIMARY KEY 作为行指针。

以上是关于如何在 django 中执行“greatest-n-per-group”查询?的主要内容,如果未能解决你的问题,请参考以下文章

Django如何使文件在django自动执行

如何在 Django 中执行批量插入?

如何在 django 迁移中执行原始 SQL

Django 模板:如何最好地抑制在 Django 模板中执行 python 代码的输出?

如何在 Django 中连接 Salesforce 数据库?使用 Python 执行 API 调用?

如何在 Django 查询集过滤中执行不等于?