用sql来判断子集

来源:互联网 发布:淘宝链接地址怎么弄 编辑:程序博客网 时间:2024/05/16 17:56

create table ken.sc(id integer,cno integer);.


insert into ken.sc values(1,1);
insert into ken.sc values(1,2);
insert into ken.sc values(1,3);
insert into ken.sc values(2,1);
insert into ken.sc values(2,2);
insert into ken.sc values(2,3);
insert into ken.sc values(2,4);
insert into ken.sc values(3,1);
insert into ken.sc values(3,2);
insert into ken.sc values(4,5);


select  x.id 
from ken.sc as x
where not exists(
select * from  ken.sc y
where y.id=1 and not exists(
select * from ken.sc z

where z.id=x.id and z.cno=y.cno));




乍一看逻辑上非常的绕不知所以然,其实分解来看还是可以容易的理解的 


1.首先分解第一步

select * from  ken.sc y
where y.id=1 and not exists(
select * from ken.sc z
where z.cno=y.cno)

这是一个空结果 是找select * from  ken.sc y where y.id=1  在全集中不存在的结果 答案肯定是没有 因为至少它子集肯定是在全集中的。


2.主要理解的突破口是第二步

select * from  ken.sc y
where y.id=1 and not exists(
select * from ken.sc z
where z.id=1 and z.cno=y.cno) 拿出来 分别的尝试 1~4 看一下结果

1和2的结果都是空 

3的结果是

  1   3

4的结果是

  1   1
  1   3
  1   2

也可以推断出 这个query查出来的是 select * from  ken.sc y where y.id=1 在后边的结果集中不存在的情况,也就是对比select * from  ken.sc y where y.id=1 后边的结果集在z缺的记录 可以看成是补集


3.最后就比较容易了z.id=x.id 会和刚才第二步的步骤一样 把所有的值都进行对比(1~4),然后最外层的not exists会把后边不存在的结果查出来,也就是除了缺子集中的元素的记录都会被查出来 很明显 只有1自己和id为2的不缺,所以在去重之后结果是 1和2


-----------------------------

另外我用了另一种比较笨的方法也实现了上面的功能


select count(cno),id from ken.sc x
where cno in (select cno from ken.sc where id=1)
group by id
having count(cno)=(select count(cno) from ken.sc where id=1);


0 0
原创粉丝点击