Bạn không thể tổng hợp một Max(Sum())
tổng hợp , nó không hợp lệ trong SQL, cho dù bạn có đang sử dụng ORM hay không. Thay vào đó, bạn phải tham gia bảng với chính nó để tìm giá trị tối đa. Bạn có thể làm điều này bằng cách sử dụng một truy vấn con. Đoạn mã dưới đây có vẻ phù hợp với tôi, nhưng hãy nhớ rằng tôi không có thứ gì đó để chạy đoạn mã này, vì vậy nó có thể không hoàn hảo.
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))
Điều này sẽ tạo ra SQL như:
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
Có thể hiệu quả hơn nếu loại bỏ tham gia trong Subquery
bằng cách sử dụng một tính năng cụ thể của chương trình phụ trợ như array_agg
(Postgres) hoặc GroupConcat
(MySQL) để thu thập Relation.ids
được nhóm lại với nhau trong truy vấn bên ngoài. Nhưng tôi không biết bạn đang sử dụng chương trình phụ trợ nào.