#表`a`表结构都如下
+——–+——————+——+—–+———+—————-+
| Field | Type | Null | Key | Default | Extra |
+——–+——————+——+—–+———+—————-+
| id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| name | int(11) | YES | | NULL | |
| is_del | tinyint(1) | YES | | 0 | |
+——–+——————+——+—–+———+—————-+
#表`b`表结构都如下
+——–+——————+——+—–+———+—————-+
| Field | Type | Null | Key | Default | Extra |
+——–+——————+——+—–+———+—————-+
| id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| name | int(11) | YES | | NULL | |
+——–+——————+——+—–+———+—————-+
在现有的业务场景中,a表中的数据做假删除set is_del=1,然后就会往表b插入一条数据,类似于触发器。当需要做恢复操作的时候,就会删除b表里面的数据。由于代码年代久远,不方便在操作删除b的数据的时候,同时触发a表数据的恢复,(具体情况,只有在实际的复杂的项目中才知道,防止牵一发而动全身的bug出现),所以只能打开b列表的时候,先去同步之前在b表的恢复数据。
那么需求就是找出a表已经删除了的,但是却没有插入到b表的数据。也就是说取出a表里面已经删除了的行(where is_del=1),而b表里面不存在的行。也就是对a表里已经删除了的行对b表的所有行取差集。
很差的做法:
select count(*) from a, b where a.id!=b.id and a.is_del=1 group by a.id
#或者是
select count(*) from a where is_del=1 and id not in (select id from b)
较优的做法:
select count(*) from a left join b on a.id=b.id where a.is_del=1 and b.id is null