Django 2.0 中的“greatest-n-per-group”查询?

Posted

技术标签:

【中文标题】Django 2.0 中的“greatest-n-per-group”查询?【英文标题】:“greatest-n-per-group” query in Django 2.0? 【发布时间】:2018-07-02 16:29:23 【问题描述】:

基本上,我想做this,但使用 django 2.0。

如果我尝试:

Purchases.objects.filter(.....).annotate(my_max=Window( expression=Max('field_of_interest'), partition_by=F('customer') ) )

我取回所有行,但将 my_max 属性添加到每条记录。

【问题讨论】:

如果在某些组中有多个具有最大价值的行怎么办?结果应该是什么? 【参考方案1】:

如果您使用的是 PostgreSQL:

Purchases.objects.filter(.....).order_by(
    'customer', '-field_of_interest'
).distinct('customer')

更新:过滤器中不允许使用窗口表达式,因此以下方法不起作用。最新解决方案请参考this answer

或使用Window 表达式

Purchases.objects.filter(.....).annotate(my_max=Window(
    expression=Max('field_of_interest'),
    partition_by=F('customer')
    )
).filter(my_max=F('field_of_interest'))

但如果他们有相同的field_of_interest,后者可以为每个客户产生多行

另一个Window,每个客户只有一行

Purchases.objects.filter(.....).annotate(row_number=Window(
        expression=RowNumber(),
        partition_by=F('customer'),
        order_by=F('field_of_interest').desc()
        )
    ).filter(row_number=1)

【讨论】:

一个跟进:当我尝试最后一个查询时,我得到一个错误:django.db.utils.NotSupportedError: Window is disallowed in the filter clause. 每行都有正确的row_number 属性,但现在我使用 python 而不是 db 来删除所有记录row_number > 1. 有什么办法吗? 哦,这出乎我的意料。我认为如果它不受支持,那么不幸的是它不受支持..

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

Django 2.0 中的“greatest-n-per-group”查询?

get_queryset中的Django 2.0 url参数

Django/tastypie 实现中的 OAuth 2.0 客户端 ID

Django 2.0:将数据从视图发送到包含在另一个模板中的模板(2 个不同的应用程序)

Django 2.0 的路由如何实现正则表达式

nginx + gunicorn + django 2.0 踩坑