使用子查询进入深水区。我有一套Carpark
s。Carpark
s 有多个Booking
s。Bookings有很多BarrierActivity
记录,就是关口的各种来来去去的事件。这些都是堆栈中的简单 FK。
预订可能会到达,但屏障摄像头无法识别它。一名工作人员会给他们打电话,但这意味着系统由于某种原因失败了。这就是我在这里想要做的。算出我的预订中有多少是通过自动方式获得的。我知道还有很多其他方法可以做到这一点,但我想用一个基于子查询的查询集来做到这一点。
我的目标相当简单。BarrierActivity
注释 0 或 1 以显示每个是否存在“条目” Booking
。注释这些值的平均值,每Carpark
。
第一部分很好。我可以在和之间做一个简单的Exists()
,然后每个预订都有 0 或 1:BarrierActivity
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
)......
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()
)
)
...我得到了 Subquery-error-of-doom: more than one row returned by a subquery used as an expression
。bookings
子查询显然返回了太多,但我如何在它到达最外层子查询之前聚合它?
我已经尝试了很多事情,但是这里将平均值重新组织到子查询中。同样的错误:
successful_bas = "... as before ..."
bookings = Booking.objects_standard.order_by().filter(
carpark=OuterRef('pk')
).values('site').annotate(
entry_success=Exists(successful_bas)
).annotate(
entry_avg=Avg(Cast('entry_success', IntegerField()))
).values('entry_avg')
Carpark.objects.order_by().annotate(
entry_hitrate=ExpressionWrapper(
Subquery(bookings, output_field=FloatField()) * 100,
output_field=FloatField()
)
)