Du kan ikke foretage en aggregering af en aggregeret Max(Sum())
, det er ikke gyldigt i SQL, uanset om du bruger ORM eller ej. I stedet skal du slutte dig til bordet for sig selv for at finde maksimum. Du kan gøre dette ved at bruge en underforespørgsel. Nedenstående kode ser rigtig ud for mig, men husk på, at jeg ikke har noget at køre dette på, så det er måske ikke perfekt.
from django.db.models import Subquery, OuterRef
annotation = {
'AcSum': Sum('intensity')
}
# The basic query is on Relation grouped by A and Category, annotated
# with the Sum of intensity
query = Relation.objects.values('a', 'b__category').annotate(**annotation)
# The subquery is joined to the outerquery on the Category
sub_filter = Q(b__category=OuterRef('b__category'))
# The subquery is grouped by A and Category and annotated with the Sum
# of intensity, which is then ordered descending so that when a LIMIT 1
# is applied, you get the Max.
subquery = Relation.objects.filter(sub_filter).values(
'a', 'b__category').annotate(**annotation).order_by(
'-AcSum').values('AcSum')[:1]
query = query.annotate(max_intensity=Subquery(subquery))
Dette skulle generere SQL som:
SELECT a_id, category_id,
(SELECT SUM(U0.intensity) AS AcSum
FROM RELATION U0
JOIN B U1 on U0.b_id = U1.id
WHERE U1.category_id = B.category_id
GROUP BY U0.a_id, U1.category_id
ORDER BY SUM(U0.intensity) DESC
LIMIT 1
) AS max_intensity
FROM Relation
JOIN B on Relation.b_id = B.id
GROUP BY Relation.a_id, B.category_id
Det kan være mere effektivt at fjerne joinforbindelsen i Subquery
ved at bruge en backend-specifik funktion som array_agg
(Postgres) eller GroupConcat
(MySQL) for at indsamle Relation.ids
der er grupperet sammen i den ydre forespørgsel. Men jeg ved ikke, hvilken backend du bruger.