Использование агрегации на подзапросе в Django ORM
У меня есть такая таблица
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, здесь же это больше похоже на получение результатов на основе временной таблицы, созданной подзапросом.
Кто-нибудь знает, как я могу этого добиться (и возможно ли это вообще)?
это должно сделать работу
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)
Допустим, у вас есть две модели в отношениях "многие ко многим", подобных следующим:
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')