【Java】求两张表的差集,Not Exists条件查询

1、问题

某公司做活动,只有我公司客户里,没有在任务表里有记录客户信息;请问该SQL怎么写?

那么该如何写这个SQL

二、解答

1、分析:
①、首先在客户表中有记录
②、任务表中没有该用户ID的用户的记录;

2、表结构
customer表:cust_id,cust_name;
taskinfo表:task_id,cust_id,cust_name;
两表之间的关系是Customer表中的cust_id等于TaskInfo表的cust_id;

3、单独写SQL:

select * from customer;
select * from taskinfo;

4、错误写法

select * from customer c
where  not exist(select * from taskinfo) ;

为什么这么写是错误的,因为我们知道,exist和not exists中的查询结果返回的是一个boolean值,不是true就是false;很明显,小括号里的内容如果有1条记录返回,那么,exists及括号里返回的就是true,加上前面的not,如果taskinfo表里只要有记录,则返回的结果必然是空;

5、正确写法

select * from customer c
where  not exist(select * from taskinfo t where t.cust_id = c.cust_id) ;

这里的关键点是,not exists 前面是不带记录的,很多同学喜欢写 c.cust_id not exists exist(...) 这样的格式是不对的;然后为了校验数据的正确性,我分别单独查了两张表:

select * from customer c;

我查出了1000条记录;

然后我又查了查任务表里的记录

select count(1) from (
select count(1) from taskinfo t group by t.cust_id
);

我查处了100条记录;
按理说,用我上面的SQL应该查出来900条记录才对,但是实际上我查出来了901条记录;为什么会多出来1条记录呢?
因为customer表中,cust_id是主键,不存在重复数据,所以customer表中的记录应该是唯一的,独立的;那么接下来只有两种可能性:
①、taskinfo表中有1条记录,他的cust_id在customer表中没有对应的记录;
②、我的SQL有问题;

为了验证自己的猜想,我们交换下两表的顺序:

select * from taskinfo t
where not exists(
select * from customer  c where c.cust_id = t.cust_id 
);

果然只查到1条记录,并且这条记录的cust_id是空的;这条应该是脏数据,所以给删掉了;

三、总结

公式
select * from A a where not exists(select * from B b where b.field = a.field);

关键是在小括号里,让A和B发生联系;尤其是要联系到A表的关联字段;

转载于:https://www.jianshu.com/p/5af3a427f5bb

猜你喜欢

转载自blog.csdn.net/weixin_33888907/article/details/91133535