【问题标题】:Using aggregation on subquery in Django ORM在 Django ORM 中对子查询使用聚合
【发布时间】:2022-01-21 10:49:00
【问题描述】:

我有一张这样的桌子

Category Subcategory Sub_subcategory
Cat_1 Subcat_1 Sub_subcat_1
Cat_1 Subcat_1 Sub_subcat_2
Cat_1 Subcat_2 Sub_subcat_3
Cat_2 Subcat_2 Sub_subcat_4
Cat_3 Subcat_3 Sub_subcat_5

我需要找出每个子类别出现在多少个类别中。 所以我根据上表的预期输出是:

Subcategory Total
Subcat_2 2
Subcat_1 1
Subcat_3 1

所以我可以通过运行以下 SQL 查询来得到它:

SELECT subcategory, count(*) total FROM (
    SELECT DISTINCT subcategory, category FROM table_1
) as temp_table GROUP BY subcategory ORDER BY total DESC

我花了很多时间尝试使用 Django ORM 获得相同的结果,但无法完成。 我希望这段代码可以工作:

subquery = Table1.objects.values('subcategory', 'category').distinct()
results = subquery.annotate(total=Count('*')).values('subcategory', 'total').order_by('-total')

但它的工作原理与子查询中没有'distinct()' 完全相同,因此它计算每个子类别的所有类别。

我也尝试在其他问题中找到类似的情况,但是带有子查询的通常与JOINing表和使用OuterRef有关,这里更像是根据子查询创建的临时表获取结果。

有谁知道我怎样才能做到这一点(或者甚至可能)?

【问题讨论】:

  • 我在发布之前浏览了这些示例,但没有找到与我类似的案例 - 当您从多个表中查询时会使用子查询,在我的情况下,子查询更像是临时表
  • @Sygol 你能编辑你的问题并包括模型吗?

标签: sql django django-orm


【解决方案1】:

这应该可以完成工作

dictionary = {}
queryset = YOUR_queryset_with_table_HERE.objects.all()

for i in queryset:
    subcategory = i.subcategory
    
    #check if subcategory already in dictionary
    #if not create it with 1, else +=1
    
    if dictionary["subcategory"]:
        dictionary["subcategory"] += 1
    else:
        dictionary["subcategory"] = 1

print(dictionary)

【讨论】:

  • 使用此方法,您可以为每次迭代生成数据库查询。
  • 是的,有 1 个数据库查询,以及在它之后使用 python 的一些逻辑
【解决方案2】:

假设您有两个处于类似这样的多对多关系的模型:

class Category(models.Model):
    category_name = models.CharField(max_length=30)

class SubCategory(models.Model):
    subcategory_name = models.CharField(max_length=30)
    category = models.ManyToManyField(Category)

那么这应该为您提供每个子类别出现的类别总数:

results = SubCategory.objects.all().annotate(total=Count('category')).values('subcategory_name', 'total')

【讨论】:

  • 我只有一个模型,没有多对多的关系
猜你喜欢
  • 2015-01-23
  • 2021-09-21
  • 1970-01-01
  • 2016-10-26
  • 2021-03-04
  • 2020-08-28
  • 2018-12-04
  • 1970-01-01
  • 2014-09-04
相关资源
最近更新 更多