Usando agregación en subconsultas en Django ORM
Tengo una tabla como esta
Categoría | Subcategoría | Subsubcategoría |
---|---|---|
Cat1 | Subcat1 | Subsubcat1 |
Cat1 | Subcat1 | Subsubcat2 |
Cat1 | Subcat2 | Subsubcat3 |
Cat2 | Subcat2 | Subsubcat4 |
Cat3 | Subcat3 | Subsubcat5 |
Y necesito encontrar en cuántas categorías aparece cada subcategoría.
Así que mi resultado esperado basado en la tabla anterior sería:
Subcategoría | Total |
---|---|
Subcat2 | 2 |
Subcat1 | 1 |
Subcat3 | 1 |
Para obtener eso, puedo ejecutar la siguiente consulta SQL:
SELECT subcategoría, count(*) total FROM (
SELECT DISTINCT subcategoría, categoría FROM tabla_1
) as tabla_temporal GROUP BY subcategoría ORDER BY total DESC
Pasé mucho tiempo intentando obtener el mismo resultado con Django ORM pero no pude lograrlo.
Esperaba que este código funcionara:
subconsulta = Table1.objects.values('subcategoría', 'categoría').distinct()
resultados = subconsulta.annotate(total=Count('*')).values('subcategoría', 'total').order_by('-total')
Pero funciona exactamente igual que sin ‘distinct()’ en la subconsulta, por lo que cuenta todas las categorías para cada subcategoría.
También intenté encontrar casos similares en otras preguntas, pero aquellos con subconsultas generalmente se relacionan con la unión de tablas y el uso de OuterRef, aquí se trata más de obtener resultados basados en una tabla temporal que se crea mediante la subconsulta.
¿Alguien sabe cómo puedo lograr eso (o si es incluso posible)?
davy.ai
Según la tabla proporcionada, el resultado esperado es encontrar en cuántas categorías aparece cada subcategoría. Se ha proporcionado una consulta SQL para lograr este resultado.
Para obtener el mismo resultado utilizando Django ORM, se puede utilizar el siguiente código:
Explicación:
values('subcategory')
: Agrupa por la columna de subcategoría.annotate(total=Count('category', distinct=True))
: Cuenta el número de categorías distintas para cada subcategoría y agrega una nueva columnatotal
en el conjunto de resultados.order_by('-total')
: Ordena el conjunto de resultados por la columnatotal
en orden descendente.Utilizando este código, podemos obtener el mismo resultado que la consulta SQL proporcionada.