in和select的技术原理:
㈠ in:先进行子查询,再进行主查询
㈡ exists:先进行主查询,再到子查询中过滤
in和exists的使用建议:
Ⅰ 如果限制性强的条件在子查询,则使用in
Ⅱ 如果限制性强的条件在主查询,则使用exists
可用查询结果集来理解上面这段话,采用最优化匹配原则:拿最小记录匹配大记录。限制性强,则结果集小;反之,则大。
注释:
① 使用exists可以将子查询结果定位常量,不影响查询结果,而且,效率高。
比如:
select e.*
from emp e
where exists
(select 1 from dept d
where e.deptno=d.deptno and
d.dname='SALES')
② not in可能会因为null而改变其行为导致和not exists结果集有出入。然而,在相关子查询下,not in和not exists的结果集是一样的。
sql exists和not exists用法
exists (sql 返回结果集,为真)
not exists (sql 不返回结果集,为真)
如下:
表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
SELECT ID,NAME FROM A WHERE EXIST (SELECT * FROM B WHERE A.ID=B.AID)
执行结果为
1 A1
2 A2
原因可以按照如下分析
SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=1)
---> SELECT * FROM B WHERE B.AID=1有值,返回真,所以有数据
SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=2)
---> SELECT * FROM B WHERE B.AID=2有值,返回真,所以有数据
SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=3)
---> SELECT * FROM B WHERE B.AID=3无值,返回假,所以没有数据
NOT EXISTS 就是反过来
SELECT ID,NAME FROM A WHERE NOT EXIST (SELECT * FROM B WHERE A.ID=B.AID)
执行结果为
3 A3
===========================================================================
EXISTS = IN,意思相同不过语法上有点点区别,好像使用IN效率要差点,应该是不会执行索引的原因
SELECT ID,NAME FROM A WHERE ID IN (SELECT AID FROM B)
NOT EXISTS = NOT IN ,意思相同不过语法上有点点区别
SELECT ID,NAME FROM A WHERE ID NOT IN (SELECT AID FROM B)
===========================================================================
EXISTS:
系统要求进行SQL优化,对效率比较低的SQL进行优化,使其运行效率更高,其中要求对SQL中的部分in/not in修改为exists/not exists
修改方法如下:
in的SQL语句
select *
from univ_subject u
where u.per_id in (select c.per_id from colle_subject c);
修改为exists的SQL语句
select *
from univ_subject u
where exists (select * from colle_subject c where u.per_id = c.per_id);
㈠ in:先进行子查询,再进行主查询
㈡ exists:先进行主查询,再到子查询中过滤
in和exists的使用建议:
Ⅰ 如果限制性强的条件在子查询,则使用in
Ⅱ 如果限制性强的条件在主查询,则使用exists
可用查询结果集来理解上面这段话,采用最优化匹配原则:拿最小记录匹配大记录。限制性强,则结果集小;反之,则大。
注释:
① 使用exists可以将子查询结果定位常量,不影响查询结果,而且,效率高。
比如:
select e.*
from emp e
where exists
(select 1 from dept d
where e.deptno=d.deptno and
d.dname='SALES')
② not in可能会因为null而改变其行为导致和not exists结果集有出入。然而,在相关子查询下,not in和not exists的结果集是一样的。
sql exists和not exists用法
exists (sql 返回结果集,为真)
not exists (sql 不返回结果集,为真)
如下:
表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
SELECT ID,NAME FROM A WHERE EXIST (SELECT * FROM B WHERE A.ID=B.AID)
执行结果为
1 A1
2 A2
原因可以按照如下分析
SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=1)
---> SELECT * FROM B WHERE B.AID=1有值,返回真,所以有数据
SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=2)
---> SELECT * FROM B WHERE B.AID=2有值,返回真,所以有数据
SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=3)
---> SELECT * FROM B WHERE B.AID=3无值,返回假,所以没有数据
NOT EXISTS 就是反过来
SELECT ID,NAME FROM A WHERE NOT EXIST (SELECT * FROM B WHERE A.ID=B.AID)
执行结果为
3 A3
===========================================================================
EXISTS = IN,意思相同不过语法上有点点区别,好像使用IN效率要差点,应该是不会执行索引的原因
SELECT ID,NAME FROM A WHERE ID IN (SELECT AID FROM B)
NOT EXISTS = NOT IN ,意思相同不过语法上有点点区别
SELECT ID,NAME FROM A WHERE ID NOT IN (SELECT AID FROM B)
===========================================================================
EXISTS:
系统要求进行SQL优化,对效率比较低的SQL进行优化,使其运行效率更高,其中要求对SQL中的部分in/not in修改为exists/not exists
修改方法如下:
in的SQL语句
select *
from univ_subject u
where u.per_id in (select c.per_id from colle_subject c);
修改为exists的SQL语句
select *
from univ_subject u
where exists (select * from colle_subject c where u.per_id = c.per_id);