如果我们在调用distinct()之后将调用链接到filter(),则在distinct之前将过滤器应用于查询。在应用distinct之后如何过滤查询的结果?
Example.objects.order_by('a','foreignkey__b').distinct('a').filter(foreignkey__b='something')
filter()产生的SQL中的where子句表示过滤器在distinct之前应用于查询。我想过滤不同的查询集。
这可能很简单,但我无法弄清楚,我无法找到任何内容。
编辑1:
我需要在ORM中执行此操作...
SELECT z.column1, z.column2, z.column3
FROM (
SELECT DISTINCT ON (b.column1, b.column2) b.column1, b.column2, c.column3
FROM table1 a
INNER JOIN table2 b ON ( a.id = b.id )
INNER JOIN table3 c ON ( b.id = c.id)
ORDER BY b.column1 ASC, b.column2 ASC, c.column4 DESC
) z
WHERE z.column3 = 'Something';
(我顺便使用Postgres。) 所以我想我要问的是"你如何在ORM中嵌套子查询?有可能吗?"我会查看文档。
很抱歉,如果我之前没有具体说明。我头脑中不清楚。
答案 0 :(得分:5)
这是一个老问题,但在使用Postgres时,您可以执行以下操作来强制对您的“区别”进行嵌套查询。行:
foo = Example.objects.order_by('a','foreign_key__timefield').distinct('a')
bar = Example.objects.filter(pk__in=foo).filter(some_field=condition)
bar是OP中请求的嵌套查询,无需求助于原始/额外等。经测试在1.10中工作但文档建议它应该至少恢复到1.7。
我的用例是过滤反向关系。如果Example有一些ForeignKey来模拟Toast,那么你可以这样做:
Toast.objects.filter(pk__in=bar.values_list('foreign_key',flat=true))
这将为您提供Toast的所有实例,其中最新的关联示例符合您的过滤条件。
关于性能的大健康警告,如果使用这个栏可能是一个巨大的查询集,你可能会有一个糟糕的时间。
答案 1 :(得分:2)
非常感谢帮助人员。我尝试了这两个建议,并且无法将这些建议付诸实践,但我认为它使我开始朝着正确的方向发展。
我最终使用
from django.db.models import Max, F
Example.objects.annotate(latest=Max('foreignkey__timefield')).filter(foreignkey__timefield=F('latest'), foreign__a='Something')
这将检查每个示例的最新foreignkey__timefield是什么,如果它是最新的和a =某事,那么保留它。如果它不是最新的或每个示例的!=那么它就被过滤掉了。
这不会嵌套子查询,但它给了我正在寻找的输出 - 而且它非常简单。如果有更简单的方法我真的想知道。
答案 2 :(得分:1)
不,你不能在一个简单的SELECT中做到这一点
正如您在评论中所说,在Django中,ORM filter
映射到SQL子句WHERE
,distinct
映射到DISTINCT
。在SQL中,DISTINCT
总是在WHERE
之后通过对结果集进行操作,例如,请参阅SQLite doc。
但你可以编写子查询来嵌套SELECT,这取决于实际的目标(我不知道你现在究竟是什么......你能详细说明吗?)
另外,对于您的查询,distinct('a')
仅保留Example
第一次出现的a
,这是您想要的吗?