子查询中带注释的Django过滤器按计数

丹尼尔·扎金(Daniil Zaikin)

这是一个抽象的简化示例。

假设我要吸引作者,并在类别大于3的类别中注释最少的书籍。

Book和Author模型,并且与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)在子查询中删除吗?

丹尼尔·扎金(Daniil Zaikin)

这是一个错误,将在Django 2.1.6版中修复。现在是工作区:

min_valuable_count_qs = 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()
)

min_valuable_count_qs.contains_aggregate = False

qs = Author.objects.annotate(min_valuable_count=min_valuable_count_qs))

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章