EXISTS 运算符用于判断查询子句是否有记录,如果有一条或多条记录存在返回 True,否则返回 False
SQL EXISTS 语法
SELECT column_name(s)
FROM table_name
WHERE EXISTS
(SELECT column_name FROM table_name WHERE condition);
- 案例一
website
表数据
access_log
表数据
要求:查找总访问量(count 字段)大于 200 的网站是否存在
EXISTS实现
SELECT
w.*
FROM
websites w
WHERE
EXISTS (
SELECT
l.count
FROM
access_log l
WHERE
l.count > 200
AND l.site_id = w.id)
IN实现
SELECT
w.*
FROM
websites w
WHERE
w.id IN (
SELECT
l.site_id
FROM
access_log l
WHERE
l.count > 200)
使用EXISTS和IN实现的结果是一样的
- 案例二
- 说明:member与group为多对多关系
member
表数据
group
表数据
member_group_relation
表数据
要求:查找未分组的member信息
EXISTS实现
SELECT
m.*
FROM
member m
WHERE
NOT EXISTS (
SELECT
r.id
FROM
member_group_relation r
WHERE
r.member_id = m.id
)
IN实现
SELECT
m.*
FROM
member m
WHERE
m.id NOT IN (
SELECT
r.member_id
FROM
member_group_relation r
)
使用EXISTS和IN实现的结果是一样的
要求:查找组一的member信息
EXISTS实现
SELECT
m.*
FROM
member m
WHERE
EXISTS (
SELECT
r.id
FROM
member_group_relation r
WHERE
r.member_id = m.id
AND EXISTS ( SELECT g.id FROM `group` g WHERE r.group_id = g.id AND g.`group_name` = '组一' )
)
IN实现
SELECT
m.*
FROM
member m
WHERE
m.id IN (SELECT
r.member_id
FROM
member_group_relation r
WHERE
r.group_id IN ( SELECT g.id FROM `group` g WHERE g.`group_name` = '组一' ))
使用EXISTS和IN实现的结果是一样的
个人总结:
exists与in关键字往往可以互换使用,其具体的区别可查阅其他的博文。
in关键字在使用中,子查询的返回结果往往是一个字段,先进行子查询的返回结果集,然后在进行外层的判断;这个时候是以子查询中的表来驱动外层的表,所以这样最好子查询是小表,外层是大表,小表驱动大表;
exists关键字在使用中,子查询的返回结果是true或者false,先进行外层的sql运算,然后在进行子查询返回结果,根据子查询返回的结果是真或者假来决定外层的结果是保留还是丢弃,如果子查询没有与外层表进行关联的话,外层结果的保留与否直接根据子查询结果的真假来判断;如果子查询与外层表进行关联的话,就需要进行外层表的扫描了,逐条判断外层结果集的每一条数据与内层的关联条件是否满足来决定保留与否;这个时候是以外层表来驱动子查询的表,所以这样最好子查询是大表,外层是小表,小表驱动大表;
在关联查询中,使用IN关键字的时候,IN的字段与子查询中的结果集字段 在EXISTS中是两个表的关联条件