SQL深入 :exist 和 in 的用法和区别
2012-09-19 17:46
716 查看
in 适用于 外大内小, 而exists适用于 外小内大!
假设如下应用:
两张表——用户表TDefUser(userid,address,phone)和消费表TAccConsume(userid,time,amount),需要查消费超过5000的用户记录。
用exists:
select * from TDefUser
where exists (select 1 from TAccConsume where TDefUser.userid=TAccConsume.userid and TAccConsume.amount>5000)
用in:
select * from TDefUser
where userid in (select userid from TAccConsume where TAccConsume.amount>5000)
通常情况下采用exists要比in效率高。
exists()后面的子查询被称做相关子查询他是不返回列表的值的.只是返回一个ture或false的结果(这也是为什么子查询里是"select 1"的原因,换成"select 6"完全一样,当然也可以select字段,但是明显效率低些)
其运行方式是先运行主查询一次 再去子查询里查询与其对应的结果如果是ture则输出,反之则不输出.再根据主查询中的每一行去子查询里去查询.
in()后面的子查询是返回结果集的,换句话说执行次序和exists()不一样.子查询先产生结果集,然后主查询再去结果集里去找符合要求的字段列表去.符合要求的输出,反之则不输出.
比如用户表TDefUser(userid,address,phone),消费表TAccConsume(userid,time,amount)数据如下:
消费表聚集索引是userid,time
数据(注意因为有聚集索引,实际存储也是按以下次序的)
1 2006-1-1 200
1 2006-1-2 300
1 2006-1-2 500
1 2006-1-3 2000
1 2006-1-3 2000
1 2006-1-4 400
1 2006-1-5 500
2 2006-1-1 200
2 2006-1-2 300
2 2006-1-2 500
2 2006-1-3 2000
2 2006-1-3 6000
2 2006-1-4 400
2 2006-1-5 8000
3 2006-1-1 7000
3 2006-1-2 30000
3 2006-1-2 50000
3 2006-1-3 20000
语句:
select * from TDefUser
where exists (select 1 from TAccConsume where TDefUser.userid=TAccConsume.userid and TAccConsume.amount>5000)
对于userid=1,需要找所有记录,才返回false,与第二个语句的效率差不多
对于userid=2,找到2006-1-3的记录,就返回true,比第而个语句的效率高
对于userid=3,第一条记录就返回true,比第二个语句的效率高
语句
select * from TDefUser
where userid in (select userid from TAccConsume where TAccConsume.amount>5000)
返回空记录集
2
2
3
3
3
3
再判断
语句
select * from TDefUser
where userid in (select userid from TAccConsume where userid=TDefUser.userid and amount>5000)
对于userid=1,需要找所有记录,返回空记录集,比较判断
对于userid=2,需要找所有记录,返回记录集
2
2
,比较判断
对于userid=3需要找所有记录,返回记录集
3
3
3
3
,比较判断
表中如果没有聚集索引,对exists每个userid查找的条数都不同,但都是<=第三个语句需要扫描的条数,极端的(比如>5000的都是在最后)与第三个语句效率相似,一般的比第二个语句快,所以说,“一般”exists比in效率高
----------------------------------------------------------------------------------
附上一篇觉得正确的文章,欢迎探讨:
in 和 exists也是很好区别的.
in 是一个集合运算符.
a in {a,c,d,s,d....}
这个运算中,前面是一个元素,后面是一个集合,集合中的元素类型是和前面的元素一样的.
而exists是一个存在判断,如果后面的查询中有结果,则exists为真,否则为假.
in 运算用在语句中,它后面带的select 一定是选一个字段,而不是select *.
比如说你要判断某班是否存在一个名为"小明"的学生,你可以用in 运算:
"小明" in (select sname from student)
这样(select sname from student) 返回的是一个全班姓名的集合,in用于判断"小明"是否为此集合中的一个数据;
同时,你也可以用exists语句:
exists (select * from student where sname="小明")
这两个涵数是差不多的, 但是由于优化方案的不同, 通常NOT EXISTS要比NOT IN 要快, 因为NOT EXISTS可以使用结合算法而NOT IN 就不行了,而EXISTS则不如IN快, 因为这时候IN可能更多的使用结合算法.
select * from 表A where exists(select * from 表B where 表B.id=表A.id)
这句相当于
select * from 表A where id in (select id from 表B)
对于表A的每一条数据,都执行select * from 表B where 表B.id=表A.id的存在性判断,如果表B中存在表A当前行相同的id,则exists为真,该行显示,否则不显示
exits适合内小外大的查询,in适合内大外小的查询
IN
确定给定的值是否与子查询或列表中的值相匹配。
EXISTS
指定一个子查询,检测行的存在。
比较使用 EXISTS 和 IN 的查询
这个例子比较了两个语义类似的查询。第一个查询使用 EXISTS 而第二个查询使用 IN。注意两个查询返回相同的信息。
USE pubs
GO
SELECT DISTINCT pub_name
FROM publishers
WHERE EXISTS
(SELECT *
FROM titles
WHERE pub_id = publishers.pub_id
AND type = 'business')
GO
-- Or, using the IN clause:
USE pubs
GO
SELECT distinct pub_name
FROM publishers
WHERE pub_id IN
(SELECT pub_id
FROM titles
WHERE type = 'business')
GO
下面是任一查询的结果集:
pub_name
----------------------------------------
Algodata Infosystems
New Moon Books
(2 row(s) affected)
exits 相当于存在量词:表示集合存在,也就是集合不为空只作用一个集合.例如 exist P 表示P不空时为真; not exist P表示p为空时 为真 in表示一个标量和一元关系的关系。例如:s in P表示当s与P中的某个值相等时 为真; s not in P 表示s与P中的每一个值都不相等时 为真
文章转载 原出处 :http://blog.sina.com.cn/s/blog_67eb150a0100kesw.html
假设如下应用:
两张表——用户表TDefUser(userid,address,phone)和消费表TAccConsume(userid,time,amount),需要查消费超过5000的用户记录。
用exists:
select * from TDefUser
where exists (select 1 from TAccConsume where TDefUser.userid=TAccConsume.userid and TAccConsume.amount>5000)
用in:
select * from TDefUser
where userid in (select userid from TAccConsume where TAccConsume.amount>5000)
通常情况下采用exists要比in效率高。
exists()后面的子查询被称做相关子查询他是不返回列表的值的.只是返回一个ture或false的结果(这也是为什么子查询里是"select 1"的原因,换成"select 6"完全一样,当然也可以select字段,但是明显效率低些)
其运行方式是先运行主查询一次 再去子查询里查询与其对应的结果如果是ture则输出,反之则不输出.再根据主查询中的每一行去子查询里去查询.
in()后面的子查询是返回结果集的,换句话说执行次序和exists()不一样.子查询先产生结果集,然后主查询再去结果集里去找符合要求的字段列表去.符合要求的输出,反之则不输出.
比如用户表TDefUser(userid,address,phone),消费表TAccConsume(userid,time,amount)数据如下:
消费表聚集索引是userid,time
数据(注意因为有聚集索引,实际存储也是按以下次序的)
1 2006-1-1 200
1 2006-1-2 300
1 2006-1-2 500
1 2006-1-3 2000
1 2006-1-3 2000
1 2006-1-4 400
1 2006-1-5 500
2 2006-1-1 200
2 2006-1-2 300
2 2006-1-2 500
2 2006-1-3 2000
2 2006-1-3 6000
2 2006-1-4 400
2 2006-1-5 8000
3 2006-1-1 7000
3 2006-1-2 30000
3 2006-1-2 50000
3 2006-1-3 20000
语句:
select * from TDefUser
where exists (select 1 from TAccConsume where TDefUser.userid=TAccConsume.userid and TAccConsume.amount>5000)
对于userid=1,需要找所有记录,才返回false,与第二个语句的效率差不多
对于userid=2,找到2006-1-3的记录,就返回true,比第而个语句的效率高
对于userid=3,第一条记录就返回true,比第二个语句的效率高
语句
select * from TDefUser
where userid in (select userid from TAccConsume where TAccConsume.amount>5000)
返回空记录集
2
2
3
3
3
3
再判断
语句
select * from TDefUser
where userid in (select userid from TAccConsume where userid=TDefUser.userid and amount>5000)
对于userid=1,需要找所有记录,返回空记录集,比较判断
对于userid=2,需要找所有记录,返回记录集
2
2
,比较判断
对于userid=3需要找所有记录,返回记录集
3
3
3
3
,比较判断
表中如果没有聚集索引,对exists每个userid查找的条数都不同,但都是<=第三个语句需要扫描的条数,极端的(比如>5000的都是在最后)与第三个语句效率相似,一般的比第二个语句快,所以说,“一般”exists比in效率高
----------------------------------------------------------------------------------
附上一篇觉得正确的文章,欢迎探讨:
in 和 exists也是很好区别的.
in 是一个集合运算符.
a in {a,c,d,s,d....}
这个运算中,前面是一个元素,后面是一个集合,集合中的元素类型是和前面的元素一样的.
而exists是一个存在判断,如果后面的查询中有结果,则exists为真,否则为假.
in 运算用在语句中,它后面带的select 一定是选一个字段,而不是select *.
比如说你要判断某班是否存在一个名为"小明"的学生,你可以用in 运算:
"小明" in (select sname from student)
这样(select sname from student) 返回的是一个全班姓名的集合,in用于判断"小明"是否为此集合中的一个数据;
同时,你也可以用exists语句:
exists (select * from student where sname="小明")
这两个涵数是差不多的, 但是由于优化方案的不同, 通常NOT EXISTS要比NOT IN 要快, 因为NOT EXISTS可以使用结合算法而NOT IN 就不行了,而EXISTS则不如IN快, 因为这时候IN可能更多的使用结合算法.
select * from 表A where exists(select * from 表B where 表B.id=表A.id)
这句相当于
select * from 表A where id in (select id from 表B)
对于表A的每一条数据,都执行select * from 表B where 表B.id=表A.id的存在性判断,如果表B中存在表A当前行相同的id,则exists为真,该行显示,否则不显示
exits适合内小外大的查询,in适合内大外小的查询
IN
确定给定的值是否与子查询或列表中的值相匹配。
EXISTS
指定一个子查询,检测行的存在。
比较使用 EXISTS 和 IN 的查询
这个例子比较了两个语义类似的查询。第一个查询使用 EXISTS 而第二个查询使用 IN。注意两个查询返回相同的信息。
USE pubs
GO
SELECT DISTINCT pub_name
FROM publishers
WHERE EXISTS
(SELECT *
FROM titles
WHERE pub_id = publishers.pub_id
AND type = 'business')
GO
-- Or, using the IN clause:
USE pubs
GO
SELECT distinct pub_name
FROM publishers
WHERE pub_id IN
(SELECT pub_id
FROM titles
WHERE type = 'business')
GO
下面是任一查询的结果集:
pub_name
----------------------------------------
Algodata Infosystems
New Moon Books
(2 row(s) affected)
exits 相当于存在量词:表示集合存在,也就是集合不为空只作用一个集合.例如 exist P 表示P不空时为真; not exist P表示p为空时 为真 in表示一个标量和一元关系的关系。例如:s in P表示当s与P中的某个值相等时 为真; s not in P 表示s与P中的每一个值都不相等时 为真
文章转载 原出处 :http://blog.sina.com.cn/s/blog_67eb150a0100kesw.html
相关文章推荐
- sql中in和exist语句的区别
- [数据库与SQL] - No.1 in、exists、all、any用法与区别
- SQL中IN和EXISTS用法的区别
- sql中exist与in的区别
- SQL中IN和EXISTS用法的区别
- 常用的SQL语句(三) - In与Exist的区别
- sql中exist与in的区别
- SQL中in与exist的区别
- SQL中IN和EXISTS用法的区别
- sql语句中in与exist not in与not exist 的区别
- SQL中------IN----和-----EXISTS-----用法的区别
- sql中exists,not exists的用法 和in()的区别
- SQL中IN和EXISTS用法的区别
- SQL中IN和EXISTS用法的区别
- SQL中IN和EXISTS用法的区别
- oracle sql 语句 in 与EXIST用法比较
- sql中exist与in的区别
- sql优化,in与exist , not in与not exist 的区别
- sql in 和 exist的区别
- SQL中IN和EXISTS用法的区别