SQL 语句中 exists和not exists的用法

exists           (返回结果集,为真)   
not exists       (不返回结果集,为真) 

表A 
ID   NAME   
1       A1 
2       A2 
3       A3 

表B 
ID   AID   NAME 
1       1       B1 
2       2       B2   
3       2       B3  

表A和表B是1对多的关系   A.ID   =>   B.AID 

 

1.SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE A.ID = B.AID);

执行结果:

ID   NAME   
1       A1 
2       A2 

原理如下:

(1)SELECT   ID,NAME   FROM   A   WHERE   EXISTS   (SELECT   *   FROM   B   WHERE   B.AID=1) 
---> SELECT   *   FROM   B   WHERE   B.AID=1有值,返回真,所以有数据

(2)SELECT   ID,NAME   FROM   A   WHERE   EXISTS   (SELECT   *   FROM   B   WHERE   B.AID=2) 
---> SELECT   *   FROM   B   WHERE   B.AID=2有值,返回真,所以有数据

(3)SELECT   ID,NAME   FROM   A   WHERE   EXISTS   (SELECT   *   FROM   B   WHERE   B.AID=3) 
---> SELECT   *   FROM   B   WHERE   B.AID=3无值,返回假,所以没有数据

得到的结果为,A.ID=1或2时才有数据,所以最终的条件等于

SELECT ID,NAME FROM A where id in (1,2);

扩展:

SELECT A.ID AID,A.NAME A_NAME,B.ID BID,B.AID B_AID,B.NAME B_NAME FROM A,B WHERE A.ID = B.AID;

多表关联时,是将相关联的记录拼合到一起,而非多次拼合(而当两张表是相同的表是,会多次拼合)

 

2. 同时,我们也可以作用于多个列

在某张表中,有A->B冲突,同时B->A冲突的记录(重复记录),我们以sid<tid的记录为真实记录

create table C(
sid number,
tid number
)

insert into c values (1,2);
insert into c values (2,1);
insert into c values (2,3);
insert into c values (3,2);
insert into c values (3,4);
insert into c values (4,3);
insert into c values (5,6);

(1)找到A<->B的记录对

select distinct *  from C C1,C C2 WHERE C1.SID =C2.TID AND C1.TID = C2.SID; (切记去重)

(2)找到其中sid>tid的记录

select distinct C1.SID,C1.TID  from C C1,C C2 WHERE C1.SID =C2.TID AND C1.TID = C2.SID and C1.SID > C1.TID

(3)删除这些记录

DELETE C WHERE EXISTS (
select distinct C1.SID,C1.TID  from C C1,C C2 WHERE C1.SID =C2.TID AND C1.TID = C2.SID and C1.SID > C1.TID
AND C.SID = C1.SID AND C.TID = C1.TID
);

此时在c表中删除的就是c.sid和c.tid符合这个条件的记录了

`EXISTS` `NOT EXISTS` 是 SQL 中用于检查子查询是否返回行的谓词。它们通常出现在 `WHERE` 子句中,并且可以优化涉及大量数据表连接的操作。 ### 1. 使用 `EXISTS` 当你想要选择那些满足特定条件记录存在的主表行时会使用它: ```sql SELECT * FROM 主表 A WHERE EXISTS ( SELECT 1 FROM 关联表 B WHERE B.关联字段 = A.关联字段 AND 条件表达式); ``` 这条语句的意思是:“从A表取出所有记录,只要能在B表找到一条或多条与之匹配并且符合条件的数据”。 **特点** - 如果内部查询的结果集为空,则结果为假; - 只要有至少一行存在即认为真; 例如,在员工数据库里查找有下属的所有经理: ```sql SELECT m.manager_id, m.name FROM managers m WHERE EXISTS (SELECT 1 FROM employees e WHERE e.manager_id = m.manager_id) ``` ### 2. 使用 `NOT EXISTS` 相反地,如果你想找的是那些没有任何相关记录的项,则应采用此语法形式: ```sql SELECT * FROM 表A a WHERE NOT EXISTS( SELECT * FROM 表B b where a.id=b.refId) ; ``` 这表示“获取所有的a,当不存在任何一个b使得b中的refId等于当前迭代到的那个a的id”。简单来说就是找出那些没有对应关系的对象。 比如我们要找没有订单的客户列表, ```sql SELECT c.* FROM customers c WHERE NOT EXISTS (SELECT o.customer_id FROM orders o WHERE o.customer_id=c.id) ``` 这两种操作对于处理一对多的关系特别有用。理解何时以及如何运用它们可以使您的SQL编写更加高效并减少不必要的全表扫描次数。 #### 性能考虑 在性能方面,`EXISTS` / `NOT EXISTS` 的效率一般优于等价的 `IN` 或者外键联合 (`JOIN`) 操作,尤其是在大数据量的情况下,因为一旦找到了满足条件的第一行就会立即停止搜索而不是继续检索剩下的部分。
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值