【问题标题】:Django query, average count distinctDjango查询,平均计数不同
【发布时间】:2016-12-25 15:00:00
【问题描述】:

我有一个Donation 模型定义为:

Donation
    project = models.ForeignKey(Project)
    user = models.CharField()

每个用户可以多次向任何项目捐款,因此在 db 中我可以拥有以下内容:

 Donation
-------------------
 project | user
-------------------
 1       |  A
 2       |  A
 3       |  A
 1       |  B
 2       |  B
 2       |  C

现在,我需要计算每个用户的不同项目的平均值,在这种情况下,它将是:

A: 3
B: 2
C: 1
=> ( 3 + 2 + 1 ) / 3 = 2

到目前为止,我有以下内容:

distinct_pairs = Donation.objects.order_by('project')
         .values('user', 'project')
         .distinct()

这给了我一个 project/user 对的不同列表,我可以在 python 中使用。

我想知道是否有query-only 方法可以做到这一点?

我的设置:

  • Django 1.8
  • PostgreSQL

【问题讨论】:

  • 只是想知道 - 为什么将用户设置为 char 字段而不是用户模型的外键?作为用户的字符字段听起来不像是最佳实践,imo
  • 因为不是“真实”用户,主要是为了简化示例。

标签: python django postgresql django-models django-queryset


【解决方案1】:

您无需对平均值求和,只需计算不同的值并除以不同用户的数量即可。 order_by 也是多余的,因为我们只需要计数。

distinct_pairs_count = Donation.objects.values('user', 'project').distinct().count()

distinct_users_count = Donation.objects.values('user').distinct().count()

average = distinct_pairs_count / float(distinct_users_count)  # in Python 2
average = distinct_pairs_count / distinct_users_count         # in Python 3

编辑:使其成为一个查询集

我认为您可以通过一个查询来实现这一点,但我现在无法检查:

from django.db.models import Count, Avg

average = Donation.objects.values('user', 'project')
             .annotate(num_projects=Count('project', distinct=True))
             .aggregate(Avg('num_projects'))

见:aggregating annotations in 1.8

【讨论】:

  • 我不确定这是否可行。考虑一次有 5 个用户为同一个项目捐款的情况。 distinct_pairs_count 是 5,distinct_projects_count 是 1,平均值是 5,而不是 1...
  • @nobe4 是的,对不起,我的意思是除以用户数量,而不是项目。我已经更新了我的答案。
  • 这是一个很好的解决方法,我会一直使用它,直到我只能找到一个查询(如果存在),谢谢。
  • @nobe4 我认为这可以通过聚合和注释来完成。检查我的编辑。
  • 看起来很有希望,它得到了正确的整数(即1,除法得到1.13)。
猜你喜欢
  • 2019-07-06
  • 1970-01-01
  • 2020-12-22
  • 2019-10-12
  • 1970-01-01
  • 2021-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多