Django ORM声明:
Model.objects.all() \
.annotate(
ord=Window(
expression=RowNumber(),
partition_by=F('related_id'),
order_by=[F("date_created").desc()]
)
) \
.filter(ord=1) \
.filter(date_created__lte=some_datetime)
导致以下SQL查询:
SELECT *
FROM (
SELECT
id, related_id, values, date_created
ROW_NUMBER() OVER (
PARTITION BY related_id
ORDER BY date_created DESC
) AS ord
FROM model_table
WHERE date_created <= 2022-02-24 00:00:00+00:00
)
WHERE ord = 1
可以看到,date_created__lte
过滤器应用于内部查询。是否可以控制语句位置精确器并将过滤器移到外部,如ord
?
2条答案
按热度按时间j5fpnvbx1#
在您的例子中,您可以将date_created__lte过滤器移动到annotate方法之前,以确保它应用于基本查询。这也将提高查询性能,因为annotate方法适用于较小的过滤数据集。
xdyibdwo2#
我找到了一种方法来实现我想要的结果:在注解查询之外应用过滤器,在本例中为
date_created__lte
。然而,这不是我想要的代码,从性能的Angular 来看,由于HASH JOIN,它很糟糕。当然,我可以编写一个原始的SQL查询,通过Django ORM解析值,但是对于一个简单的嵌套子查询来说,这看起来太重了。所以,一个更好的答案是赞赏🙏