【网学网提醒】:本文主要为网学会员提供SQL中exists和in的区别,希望对需要SQL中exists和in的区别网友有所帮助,学习一下!
SQL中exists和in的区别收藏
EXISTS
指定一个子查询,检测行的存在。
语法
EXISTSsubquery
参数
subquery
是一个受限的SELECT语句(不允许有COMPUTE子句和INTO关键字)。有关更多信息,请参见SELECT中有关子查询的讨论。
结果类型
Boolean
结果值
如果子查询包含行,则返回TRUE。
IN
确定给定的值是否与子查询或列表中的值相匹配。
语法
test_expression[NOT]IN
(
subquery
|expression[,...n]
)
参数
test_expression
是任何有效的Microsoft?SQLServer?表达式。
subquery
是包含某列结果集的子查询。该列必须与test_expression有相同的数据类型。
expression[,...n]
一个表达式列表,用来测试是否匹配。所有的表达式必须和test_expression具有相同的类型。
结果类型
布尔型
结果值
如果test_expression与subquery返回的任何值相等,或与逗号分隔的列表中的任何expression相等,那么结果值就为TRUE。否则,结果值为FALSE。
使用NOTIN对返回值取反。
比较
假设如下应用:
两张表——用户表TDefUser(userid,address,phone)和消费表TAccConsume(userid,time,amount),需要查消费超过5000的用户记录。
用exists:
select*fromTDefUser
whereexists(select1fromTAccConsumewhereTDefUser.userid=TAccConsume.useridandTAccConsume.amount>5000)
用in:
select*fromTDefUser
whereuseridin(selectuseridfromTAccConsumewhereTAccConsume.amount>5000)
通常情况下采用exists要比in效率高。
exists()后面的子查询被称做相关子查询他是不返回列表的值的.只是返回一个ture或false的结果(这也是为什么子查询里是"select1"的原因,换成"select6"完全一样,当然也可以select字段,但是明显效率低些)
其运行方式是先运行主查询一次再去子查询里查询与其对应的结果
如果是ture则输出,反之则不输出.
再根据主查询中的每一行去子查询里去查询.
in()后面的子查询是返回结果集的,换句话说执行次序和exists()不一样.
子查询先产生结果集,然后主查询再去结果集里去找符合要求的字段列表去.
符合要求的输出,反之则不输出.
比如用户表TDefUser(userid,address,phone),消费表TAccConsume(userid,time,amount)数据如下:
消费表聚集索引是userid,time
数据(注意因为有聚集索引,实际存储也是按以下次序的)
12006-1-1200
12006-1-2300
12006-1-2500
12006-1-32000
12006-1-32000
12006-1-4400
12006-1-5500
22006-1-1200
22006-1-2300
22006-1-2500
22006-1-32000
22006-1-36000
22006-1-4400
22006-1-58000
32006-1-17000
32006-1-230000
32006-1-250000
32006-1-320000
语句一:
select*fromT
DefUser
whereexists(select1fromTAccConsumewhereTDefUser.userid=TAccConsume.useridandTAccConsume.amount>5000)
对于userid=1,需要找所有记录,才返回false,与第二个语句的效率差不多
对于userid=2,找到2006-1-3的记录,就返回true,比第而个语句的效率高
对于userid=3,第一条记录就返回true,比第二个语句的效率高字串6
语句二:
select*fromTDefUser
whereuseridin(selectuseridfromTAccConsumewhereTAccConsume.amount>5000)
返回空记录集
2
2
3
3
3
3
再判断
语句三:
select*fromTDefUser
whereuseridin(selectuseridfromTAccConsumewhereuserid=TDefUser.useridandamount>5000)
对于userid=1,需要找所有记录,返回空记录集,比较判断
对于userid=2,需要找所有记录,返回记录集
2
2
,比较判断
对于userid=3需要找所有记录,返回记录集
3
3
3
3
,比较判断
表中如果没有聚集索引,对exists每个userid查找的条数都不同,但都是<=第三个语句需要扫描的条数,极端的(比如>5000的都是在最后)与第三个语句效率相似,一般的比第二个语句快,所以说,“一般”exists比in效率高
本文来自CSDN博客,转载请标明出处:blog.csdn.net/Tercel99/archive/2008/03/04/2146767.aspx