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