当前位置: 首页 > 面试题库 >

Django 1.11注释子查询聚合

阎德业
2023-03-14
问题内容

这是我目前最喜欢使用的一项前沿功能,并且很快就会消失。我想将子查询聚合注释到现有查询集上。在1.11之前执行此操作意味着自定义SQL或修改数据库。这是this的文档以及其中的示例:

from django.db.models import OuterRef, Subquery, Sum
comments = Comment.objects.filter(post=OuterRef('pk')).values('post')
total_comments = comments.annotate(total=Sum('length')).values('total')
Post.objects.filter(length__gt=Subquery(total_comments))

他们在总体上进行注释,这对我来说似乎很奇怪,但是无论如何。

我正在为此而苦苦挣扎,所以我将其沸腾回到我拥有数据的最简单的真实示例中。我有Carpark,其中包含许多Space。使用Book→Authorif会使你更快乐,但是-暂时-我仅想使用Subquery* 注释相关模型的数量。

spaces = Space.objects.filter(carpark=OuterRef('pk')).values('carpark')
count_spaces = spaces.annotate(c=Count('*')).values('c')
Carpark.objects.annotate(space_count=Subquery(count_spaces))

这给了我一个可爱,ProgrammingError: more than one row returned by a subquery used as an expression并且在我的脑海中,这个错误是很合理的。子查询返回带注释的总数的空格列表。

该示例建议发生某种魔术,最后我得到一个可以使用的数字。但这不是在这里发生吗?如何注释汇总的子查询数据?

嗯,正在向查询的SQL添加一些内容…
我建立了一个新的停车场/太空模型,它起作用了。因此,下一步是弄清楚是什么使我的SQL中毒了。在Laurent的建议下,我看了一下SQL,并尝试使其更像他们在答案中发布的版本。这是我发现真正问题的地方:

SELECT "bookings_carpark".*, (SELECT COUNT(U0."id") AS "c"
FROM "bookings_space" U0
WHERE U0."carpark_id" = ("bookings_carpark"."id")
GROUP BY U0."carpark_id", U0."space"
)
AS "space_count" FROM "bookings_carpark";

我已经突出显示了它,但这是该子查询的GROUP BY ... U0."space"。由于某种原因,它们都在重新调整。调查仍在继续。

编辑2:好吧,只要查看子查询SQL,通过through我就可以看到第二组

In [12]: print(Space.objects_standard.filter().values('carpark').annotate(c=Count('*')).values('c').query)
SELECT COUNT(*) AS "c" FROM "bookings_space" GROUP BY "bookings_space"."carpark_id", "bookings_space"."space" ORDER BY "bookings_space"."carpark_id" ASC, "bookings_space"."space" ASC

编辑3:好吧!这两种模型都有排序顺序。这些被传送到子查询。这些订单使我的查询膨胀并中断了查询。

我想这可能是在Django一个错误,但短于这两种模式移除元ORDER_BY的,有没有什么办法可以不排序在querytime查询?


问题答案:

我只需要从模型中删除规定的元顺序。你可以通过.order_by()在子查询中添加一个空白来实现。在我的代码中,这意味着:

spaces = Space.objects.filter(carpark=OuterRef('pk')).order_by().values('carpark')
count_spaces = spaces.annotate(c=Count('*')).values('c')
Carpark.objects.annotate(space_count=Subquery(count_spaces))


 类似资料:
  • 问题内容: 我想要做的是计算子查询返回的行数,本质上如下: 这是我的错误信息: 为什么这不起作用?如果select仅返回一堆具有过滤条件的行,为什么我不能计算行数或返回的行数? 我正在计算拥有的不同员工的数量。按分组。 这是有关我的数据库的一些结构信息,作为查询的一部分。 谢谢! 问题答案: 试试这个 或这个

  • 我有以下JPA实体(getter、setter和非相关字段省略): 我的目标是使用JPQL或criteriaAPI实现查询,它将返回每天的平均事务量和最大事务量。 产生预期结果的原生SQL查询(MySQL数据库)如下所示: 遗憾的是,不鼓励使用本机 SQL 查询,并且 JPQL 不允许在 where 子句中使用子查询。 提前谢谢你。 附加: 我从以下Spring数据查询开始: 但显然没有用: 我可

  • 我试图在elasticsearch spring数据中使用@query annotation来进行复杂的查询,但当我尝试下面的简单查询时,我得到了一个错误 堆栈跟踪

  • 我目前正在尝试向我的REST API添加一个新功能。 基本上,我想添加在路径末尾添加查询参数的功能,并将其转换为所有查询选项的映射,例如。 我当前的代码允许我做这样的事情 这将使用所有@pathparam作为字符串变量来生成响应。 我现在想做的是添加: 然后我会让它生成一个映射,可以和pathparam一起用来构建响应 我在想这样的事情[下图]然而@QueryParam似乎只处理一个键值,而不是它

  • >[danger] 注意!!! 使用聚合功能时,必须给它一个别名,以便能够从模型中访问它 > 聚合函数的计算,都是排除了 null 值,所以COUNT( id ) 一般推荐用非空的主键来计算 COUNT 计算数量 const { Sequelize } = app; // 查询班级总人数,按照姓名聚合 const ret = await Student.findAll({ attribut

  • 在应用中我们经常会用到一些统计数据,例如当前所有(或者满足某些条件)的用户数、所有用户的最大积分、用户的平均成绩等等,ThinkPHP为这些统计操作提供了一系列的内置方法,包括: 方法 说明 count 统计数量,参数是要统计的字段名(可选) max 获取最大值,参数是要统计的字段名(必须) min 获取最小值,参数是要统计的字段名(必须) avg 获取平均值,参数是要统计的字段名(必须) sum