Django ORM如何在WHERE语句中执行聚合子查询?

s5a0g9ez  于 2023-04-13  发布在  Go
关注(0)|答案(1)|浏览(101)

我试图构造以下类似于Django ORM的查询:
SELECT * FROM table WHERE depth = (SELECT MIN(depth) FROM table)
如何用Django ORM表示法来写呢?到目前为止,似乎很难使用这样的聚合,因为QuerySet.aggregate()不是惰性计算,而是直接执行。
我知道这个基本的例子可以写成Model.objects.filter(depth=Model.objects.aggregate(m=Min('depth'))['m']),但是它不能进行惰性计算,需要两个独立的查询。对于我更复杂的情况,我肯定需要一个惰性计算的查询集。
仅供参考,我尝试过但失败了:

  • 一个带有Model.objects.order_by().values().annotate(m=Min('depth').values('m'))的子查询将导致一个似乎很难释放的GROUP BY id
  • 带有Model.objects.annotate(m=Min('depth')).filter(depth=F('m'))的子查询将给予一个GROUP BY id,并将m值包含在主结果中,这就是annotate所做的。

我目前的解决方法是使用QuerySet.extra(where=[...]),但我更希望看到ORM生成该代码。

vc6uscn9

vc6uscn91#

这个应该能用

MyModel.objects.filter(
    depth=MyModel.objects.annotate(min_depth=Min('depth)).values('min_depth')[:1]
)

使用annotate而不是aggregate将使查询集保持惰性。

相关问题