背景:
create table test as select * from bda_objects;
insert into test select * from test;
此时test表,有2份数据是重复的,需求:
把所有重复的数据删除,只保留一份数据。
用exists删:
delete test a
where exists(select b.object_id
from test b
where a.object_id = b.object_id
and a.rowid < b.rowid);——成功
等价改成用in删:
delete test a
where a.object_id in (select b.object_id
from test b
where a.object_id = b.object_id
and a.rowid < b.rowid);——成功——为啥这样写就能成功?
改成这样的:
delete test a
where a.rowid in (select b.rowid
from test b
where a.object_id = b.object_id
and a.rowid < b.rowid);——失败,删除0条——不知道为啥?
你最后这个sql的确是删不掉数据的,"a.rowid in (select b.rowid ...) "表示 要找出 "a.rowid=b.rowid"的数据,但是这个in里面,又有这个条件"a.rowid < b.rowid",既等于又小于,这两个条件是不可能同时成立的,因此找不到数据。
另外,你第一个sql
delete test a
where exists(select b.object_id
from test b
where a.object_id = b.object_id
and a.rowid < b.rowid);
其实子查询里select 的字段可以为任何东西,你select 1都行,比如
delete test a
where exists(select 1
from test b
where a.object_id = b.object_id
and a.rowid < b.rowid);
因为它的重点不在于select了哪个字段,而是在于后面的这两个条件 object_id 和 rowid,
可以发现,object_id是用的相等,所以object_id可以用in找到;而rowid是小于,当然就不能用in找到了
如果你执行了这个之后
delete test a
where a.object_id in (select b.object_id
from test b
where a.object_id = b.object_id
and a.rowid < b.rowid);
再去执行另一个删除语句的话,那就找不到需要删除的记录了。
您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!