【问题标题】:Django order_by() filter with distinct()Django order_by() 过滤器与 distinct()
【发布时间】:2014-01-02 04:38:54
【问题描述】:

我怎样才能像这样创建order_by ....

p = Product.objects.filter(vendornumber='403516006')\
                   .order_by('-created').distinct('vendor__name')

问题是我有多个同名的供应商,我只想要供应商的最新产品..

希望它有意义吗?

我收到了这个数据库错误:

SELECT DISTINCT ON 表达式必须匹配初始 ORDER BY 表达式 第 1 行:选择 DISTINCT ON ("search_vendor"."name") “搜索产品”...

【问题讨论】:

    标签: django django-models django-aggregation django-filters


    【解决方案1】:

    根据您的错误消息和this other question,在我看来这可以解决它:

    p = Product.objects.filter(vendornumber='403516006')\
                   .order_by('vendor__name', '-created').distinct('vendor__name')
    

    也就是说,DISTINCT ON 表达式似乎必须匹配最左边的 ORDER BY 表达式。因此,通过将您在distinct 中使用的列作为order_by 中的第一列,我认为它应该可以工作。

    【讨论】:

    • 但是使用这种方法,它将首先按供应商名称排序,并且仅使用“created”作为二级排序。这意味着“创建”的顺序将不正确。 docs.djangoproject.com/en/1.10/ref/models/querysets/#order-by
    • @Ness 你说的是真的。但不一定相关。看来 OP 对通过created 订购不感兴趣。他使用created 不是为了订购最终结果,而是为了获得每个供应商的正确记录。在 OP 的用例中,供应商的顺序似乎并不重要。事实上,我们不知道真正的预期顺序,它基本上没有被 OP 指定。
    • 谢谢,真的不是很明显的事情。
    • 如果我想按其他东西排序但在另一列中有不同的值怎么办?
    • 谢谢!你让我开心。
    【解决方案2】:

    仅匹配最左边的 order_by() arg 和 distinct() 对我不起作用,产生相同的错误(Django 1.8.7 错误或功能)?

    qs.order_by('project').distinct('project')
    

    但是当我改为:

    qs.order_by('project__id').distinct('project')
    

    我什至没有多个 order_by 参数。

    【讨论】:

    • 这是唯一对我运行 Django 2.0.2 和 PostgreSQL 10.1 有效的方法。我尝试了涉及匹配order_bydistinct 的参数顺序的其他建议,但这些都没有解决问题。
    • 同样的问题,不知道为什么需要 _id
    • 我也成功地将 __id 添加到 order_by() 但不是 distinct()
    • @dowjones123 原因可能是相关模型上定义的默认排序(此答案中的项目)。 'distinct()' 描述中最后一个注释中的文档mentions this case
    【解决方案3】:

    如果您希望使用单独的字段来区分并按另一个字段排序,您可以使用以下代码

    from django.db.models import Subquery
    
    Model.objects.filter(
        pk__in=Subquery(
           Model.objects.all().distinct('foo').values('pk')
        )
    ).order_by('bar')
    

    【讨论】:

    • 据我所知,这不适用于与预取相关的...
    • 其他答案对我不起作用,因为我需要稍后从同一个查询集中对其他字段执行排序。这个有效。
    • 这对我有用 - 但需要 order_by ... Model.objects.all().order_by('foo').distinct('foo').values('pk') ...
    【解决方案4】:

    我遇到了类似的问题,但后来涉及相关领域。仅在distinct() 中添加相关字段,我没有得到正确的结果。

    我想按room__name 排序,保持person(链接到residency)的唯一性。按照以下重复相关字段修复了我的问题:

    .order_by('room__name', 'residency__person', ).distinct('room__name', 'residency__person')
    

    另请参阅这些相关帖子:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-04
      • 1970-01-01
      • 2015-04-30
      • 2012-06-29
      • 1970-01-01
      • 1970-01-01
      • 2015-04-30
      相关资源
      最近更新 更多