同表查询筛选记录:如何排除id存在于old_id字段的符合条件条目
问题描述
假设我们有一张表结构如下:
+--------------- ... | id | old_id | +--------------- ... | ...
请问如何选择满足自定义条件的所有记录,但排除那些id出现在old_id列中的条目?
我尝试过以下代码,但没有效果:
records = MyRecords.objects\ .filter(<my custom criteria>)\ .exclude(id__in=models.OuterRef('old_id'))\ .order_by('-modified_at')
我想要实现的效果等同于以下SQL语句:
select * from mytable where <custom criteria> and not id in (select old_id from mytable where 1)
解决方案
你需要用Subquery来获取所有old_id的集合,再结合exclude实现需求,代码如下:
from django.db.models import Subquery # 先获取所有非空的old_id(如果要包含空值可以去掉filter) old_ids_subquery = MyRecords.objects.filter(old_id__isnull=False).values('old_id') records = MyRecords.objects\ .filter(<my custom criteria>)\ .exclude(id__in=Subquery(old_ids_subquery))\ .order_by('-modified_at')
补充说明
Subquery(old_ids_subquery)会生成你目标SQL里的子查询逻辑,和select old_id from mytable where 1行为一致(过滤空值是因为NULL不会被IN条件匹配,和原生SQL默认行为对齐)- 要是不需要过滤空的
old_id,直接用MyRecords.objects.values('old_id')作为子查询就行
内容的提问来源于stack exchange,提问作者Lex Podgorny
相关产品推荐
相关产品推荐

