关于 SQL EXISTS/IN运算符的学习

EXISTS 运算符用于判断查询子句是否有记录,如果有一条或多条记录存在返回 True,否则返回 False

SQL EXISTS 语法

SELECT column_name(s)
FROM table_name
WHERE EXISTS
(SELECT column_name FROM table_name WHERE condition);
  • 案例一
    website表数据
    webSite表结构及数据

access_log表数据
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表数据
member表数据

group表数据
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中是两个表的关联条件
图解字段转换关系

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值