Django QuerySet:用于计数值出现的附加字段

Posted

技术标签:

【中文标题】Django QuerySet:用于计数值出现的附加字段【英文标题】:Django QuerySet: additional field for counting value's occurence 【发布时间】:2018-12-11 13:13:08 【问题描述】:

我有一个包含 100 个项目的 QuerySet 对象,对于每个项目,我需要知道特定 contract_numbercontract_number 字段中出现的次数。

预期输出示例:

['contract_number': 123, 'contract_count': 2, 'contract_number': 456, 'contract_count': 1 ...]

这意味着值 123 在整个 contract_number 字段中出现了 2 次。

重要的一点:我不能减少项目的数量,所以分组在这里不起作用。

与此等效的 SQL 将是一个附加字段 contract_count,如下所示:

 SELECT *,
 (SELECT count(contract_number) FROM table where t.contract_number = contract_number) as contract_count
FROM table as t

问题是如何使用 Python 对象来做到这一点。经过一些研究,我发现对于更复杂的查询,应该使用Queryset extra method。以下是我的尝试之一,但结果不是我所期望的

    queryset = Tracker.objects.extra(
    select=
        'contract_count': '''
        SELECT COUNT(*)
        FROM table
        WHERE contract_number = %s
        '''
    ,select_params=(F('contract_number'),),)

我的models.py

class Tracker(models.Model):
    contract_number = models.IntegerField()

编辑: 我的问题的解决方案是Subquery()

【问题讨论】:

【参考方案1】:

你可以像这样使用注解:

from django.db.models import Count
Tracker.objects.values('contract_number').annotate(contract_count=Count('contract_number')).order_by()

【讨论】:

很有趣,但是我得到的不是预期的输出,而是值:每个项目 1。当然,有些合同是重复的 @Supergator 我想这是因为默认排序。尝试在我的更新中添加order_by()。在此处查看详细信息:docs.djangoproject.com/en/2.0/topics/db/aggregation/… 谢谢,那是真的,我之前在我的查询中有一些订单。现在,我得到了很好的计数值,问题是,它减少了输出中的项目数量 - 如果项目,我必须保持原始数量。 你有什么想法,如何在不减少项目数量的情况下获得计数值? 这正是我所需要的,非常感谢您的支持

以上是关于Django QuerySet:用于计数值出现的附加字段的主要内容,如果未能解决你的问题,请参考以下文章

如何在 django 注释中从 0 开始计数?

在Django QuerySet上计算vs len

Django 将日期解析为 QuerySet 中的 dd-mm-yyyy

django queryset 返回“类名对象”而不是 DB 值

为啥带有 Q() 表达式的 Django QuerySet 返回重复值?

Django Queryset 获取所有值并首先相关