Вот абстрактный и упрощенный пример.
Скажем, я хочу получить авторов и аннотировать минимальное количество книг в категории, если оно больше трех.
Книжная и авторская модели и не связаны с полями ForeignKey (помните, абстрактно и упрощенно, есть причина):
Author(models.Model):
name = models.CharField(max_length=250)
Book(models.Model):
author_name = models.CharField(max_length=250)
book_category = models.CharField(max_length=250)
Вот самый простой запрос, который я могу воспроизвести:
(Author.objects
.annotate(min_valuable_count=Subquery(
Book.objects
.filter(author_name=OuterRef('name'))
.annotate(cnt=Count('book_category'))
.filter(cnt__gt=3)
.order_by('cnt')
.values('cnt')[:1],
output_field=models.IntegerField()
))
)
И я получаю ошибку:
psycopg2.ProgrammingError: missing FROM-clause entry for table "U0"
LINE 1: ... "core_author" GROUP BY "core_author"."id", "U0"."id" ...
^
Вот SQL:
SELECT "core_author"."id", "core_author"."name", (
SELECT COUNT(U0."book_category") AS "cnt"
FROM "core_book" U0 WHERE U0."id" = ("core_author"."chat_id")
GROUP BY U0."id" HAVING COUNT(U0."book_category") > 3
ORDER BY "cnt" ASC LIMIT 1)
AS "min_valuable_count"
FROM "core_author"
GROUP BY "core_author"."id", "U0"."id"
Обновление № 1
Я обнаружил, что удаление .filter(cnt__gt=3)
удаляет последние GROUP BY
, которые не имеют доступа к U0
:
SELECT "core_author"."id", "core_author"."name", (
SELECT COUNT(U0."book_category") AS "cnt"
FROM "core_book" U0 WHERE U0."id" = ("core_author"."chat_id")
GROUP BY U0."id"
ORDER BY "cnt" ASC LIMIT 1)
AS "min_valuable_count"
FROM "core_author"
Есть ли способ удалить GROUP BY
во внешнем запросе, не удаляя .filter(cnt__gt=3)
в подзапросе?