使用Subquery进入深水区。我有一套Carpark
s。 Carpark
有多个Booking
个。预订有许多BarrierActivity
条记录,这些记录是障碍中各种即将到来的事件。这些都是堆栈中的简单FK。
预订可能会到达且障碍物相机不识别它。一名工作人员会嗡嗡作响,但这意味着系统因某种原因失败了。这就是我在这里要做的事情。通过自动化方式计算出我预订的百分比。我知道有很多其他方法可以做到这一点,但我想用一个基于子查询的查询集来做这个。
我的目标相当简单。注释0或1以显示每个BarrierActivity
是否存在“条目”Booking
。根据{{1}}注释这些值的平均值。
第一部分没问题。我可以在Carpark
和Exists()
之间做一个简单的BarrierActivity
,然后每个预订都有0或1:
Booking
再次,这很好。但是一旦我尝试将其扩展到另一个层(所以看successful_bas = BarrierActivity.objects.order_by().filter(
booking=OuterRef('pk'),
activity_type=BarrierActivity.TYPE_ANPR_BOOKING,
direction='entry'
).values('booking')
Booking.objects.order_by().annotate(
entry_success=Exists(successful_bas)
)
而不是Carpark
)...
Booking
...我得到了Subquery-of-doom:successful_bas = BarrierActivity.objects.order_by().filter(
booking=OuterRef('pk'),
activity_type=BarrierActivity.TYPE_ANPR_BOOKING,
direction='entry'
).values('booking')
bookings = Booking.objects.order_by().filter(
carpark=OuterRef('pk')
).values('carpark').annotate(
entry_success=Exists(successful_bas)
).values('entry_success')
Carpark.objects.order_by().annotate(
entry_hitrate=ExpressionWrapper(
Avg(Cast(Subquery(bookings), IntegerField())) * 100,
output_field=FloatField()
)
)
。 more than one row returned by a subquery used as an expression
子查询明显返回太多但是如何在它到达最外面的子查询之前聚合它?
我尝试了很多东西,但这里是对子查询中平均值的重组。同样的错误:
bookings
答案 0 :(得分:0)
我能够在自己的一个项目中重新创建部分内容,并在外部子查询中添加distinct('<values_field_name>').order_by()
解决了它。
需要使用distinct调用来减少返回的行数。不同调用中的字段名称是必需的,否则它会尝试跨另一个字段执行不同的调用。然后order_by()
调用清除任何排序,以便查询对与初始表达式排序匹配的distinct表达式进行排序。
这是我尝试的:
successful_bas = BarrierActivity.objects.order_by().filter(
booking=OuterRef('pk'),
activity_type=BarrierActivity.TYPE_ANPR_BOOKING,
direction='entry'
).values('booking')
bookings = Booking.objects.order_by().filter(
carpark=OuterRef('pk')
).annotate(
entry_success=Exists(successful_bas)
).values('carpark').distinct('carpark').order_by()
Carpark.objects.order_by().annotate(
entry_hitrate=ExpressionWrapper(
Avg(Cast(Subquery(bookings), IntegerField())) * 100,
output_field=FloatField()
)
)
请注意,我删除了外部子查询中的values
调用之一。