对以下表执行自连接查询:
> select * from test_users
id email
--- -----------
1 "a@abc.com"
2 "a@abc.com"
3 "b@abc.com"
我可以使用SQL:
> select u1.id u1id, u2.id u2id from test_users u1 inner join test_users u2 on u1.email=u2.email and u1.id !=u2.id
u1id u2id
----- ------
1 2
2 1
问题:
- 我如何在Django ORM中写这个?
- 如果我想删除重复,以便在上面的例子中我只得到1行,我如何在Django中实现?
可以通过Exists
检索主键大于(或小于)用户主键的User
s。子查询(Django-doc):
from django.db.models import Exists, OuterRef
Users.objects.filter(
Exists(
User.objects.filter(
pk__gt=OuterRef('pk'),
email=OuterRef('email')
)
)
)
如果在这些对象上调用.delete()
,则将删除所有存在另一个Users
对象且具有更大主键的User
。
在django-3.0之前,应该将Exists
子查询移动到.annotate(…)
子句,然后在此进行过滤:
from django.db.models import Exists, OuterRef
Users.objects.annotate(
has_other=Exists(
User.objects.filter(
pk__gt=OuterRef('pk'),
email=OuterRef('email')
)
)
).filter(has_other=True)