sql语句中关键字Exists 与 in 的区别,看下列实例
DECLARE @t table(id int,do varchar(10),name varchar(10))
INSERT @t SELECT 1,'1','a'
INSERT @t SELECT 2,'1','b'
INSERT @t SELECT 3,'2','a'
INSERT @t SELECT 4,'3','c'
INSERT @t SELECT 5,'2','a'
INSERT @t SELECT 6,'1','b'
INSERT @t SELECT 7,'1','a'
---------------------
正解语句:select * from @t a where exists(select 1 from @t where id>a.id and do=a.do and name=a.name)
如果我把语名改为:
select * from @t a where id in (select id from @t where id>a.id and do=a.do and name=a.name)
为什么没有任何结果
问题点数:5、回复次数:14Top
1 楼itblog(Just for wife!)回复于 2006-06-04 08:23:33 得分 0
select * from @t a where id in (select min(id) from @t group by do,name having count(id)>1)Top
2 楼ll_e_mail()回复于 2006-06-04 08:31:10 得分 0
itblog(^ω^)的语句也是正解.
-------------------------
但我不明白,这什么我的语名
select * from @t a where id in (select id from @t where id>a.id and do=a.do and name=a.name)
没有任何结果,我想和select * from @t a where exists(select 1 from @t where id>a.id and do=a.do and name=a.name)应用相同的结果
Top
3 楼aw511(点点星灯)回复于 2006-06-04 08:35:07 得分 0
楼主,这两句话所要的意思是不想同的,我不知道怎么表达其中的区别
你可以看看下面的这个例子,可以帮助你理解
比较使用 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)
Top
4 楼aw511(点点星灯)回复于 2006-06-04 08:45:25 得分 0
DECLARE @t table(id int,do varchar(10),name varchar(10))
INSERT @t SELECT 1,'1','a'
INSERT @t SELECT 2,'1','b'
INSERT @t SELECT 3,'2','a'
INSERT @t SELECT 4,'3','c'
INSERT @t SELECT 5,'2','a'
INSERT @t SELECT 6,'1','b'
INSERT @t SELECT 7,'1','a'
---------------------
select * from @t
--正解语句:
select * from @t a where exists(select 1 from @t where id>a.id and do=a.do and name=a.name)
select * from @t a where exists(select 1 from @t where id>a.id and do=a.do and name=a.name and id=a.id)
--注意
--exists 相当在in中加了一个相等的条件
--如果我把语名改为:
select * from @t a where id in (select id from @t where id>a.id and do=a.do and name=a.name)
--此句通过分析可以看出IN后面是没有任何的数据的
select * from @t a where id in (select min(id) from @t group by do,name having count(id)>1)
--一楼写的这句就可以提取按照do,name组合,当条数大于1的取最小的ID
--关键是exists 相当在in中加了一个相等的条件
--不知道这样理解对不对
Top
5 楼ll_e_mail()回复于 2006-06-04 09:40:53 得分 0
select * from @t a where id in (select id from @t where id>a.id and do=a.do and name=a.name)
--此句通过分析可以看出IN后面是没有任何的数据的
----------------------------------------
如果把主表的指针定为id=1时,按子表的查询条件,结果应为第七条记录.
也就是:select id from @t where id>1 and do=1 and name=a
结果id=7,是有数据的.Top
6 楼caobin518(linlin)回复于 2006-06-04 10:48:50 得分 0
收藏Top
7 楼hhwlc(欧文)回复于 2006-06-04 17:19:28 得分 0
markTop
8 楼LouisXIV(夜游神)回复于 2006-06-04 21:27:10 得分 0
select * from @t a where id in (select id from @t where id>a.id and do=a.do and name=a.name)
--此句通过分析可以看出IN后面是没有任何的数据的
----------------------------------------
如果把主表的指针定为id=1时,按子表的查询条件,结果应为第七条记录.
也就是:select id from @t where id>1 and do=1 and name=a
结果id=7,是有数据的.
-----------------------------------------
此时主表的id是1,而子查询获得的结果是7,因为1不属于(7),所以不会有任何结果输出Top
9 楼ll_e_mail()回复于 2006-06-04 21:41:58 得分 0
DECLARE @t table(id int,do varchar(10),name varchar(10))
INSERT @t SELECT 1,'1','a'
INSERT @t SELECT 2,'1','b'
INSERT @t SELECT 3,'2','a'
INSERT @t SELECT 4,'3','c'
INSERT @t SELECT 5,'2','a'
INSERT @t SELECT 6,'1','b'
INSERT @t SELECT 7,'1','a'
select * from @t where id in (7)
-------------------------------------
结果:
id do name
----------- ---------- ----------
7 1 a
(所影响的行数为 1 行)Top
10 楼LouisXIV(夜游神)回复于 2006-06-04 22:18:33 得分 0
不是说表@a中不存在id=7的数据
而是在你所写的查询
select * from @t a where id in (select id from @t where id>a.id and do=a.do and name=a.name)
中
但主查询的id指针指向1时,子查询求得的结果为7,由于1!=7,所以主查询不会输出结果
不知道你能不能理解??Top
11 楼billpu(加勒比小飞猪)回复于 2006-06-05 08:54:26 得分 5
我觉得楼主对子查询的类型有点混淆 我就依照我的理解来说说
exists()后面的子查询被称做相关子查询 他是不返回列表的值的.只是返回一个ture或false的结果(这也是为什么子查询里是"select 1"的原因 当然也可以select任何东西)
其运行方式是先运行主查询一次 再去子查询里查询与其对应的结果 如果是ture则输出,反之则不输出.再根据主查询中的每一行去子查询里去查询.
in()后面的子查询 是返回结果集的,换句话说执行次序和exists()不一样.子查询先产生结果集,然后主查询再去结果集里去找符合要求的字段列表去.符合要求的输出,反之则不输出.
解释一下楼主感到疑惑的
(如果把主表的指针定为id=1时,按子表的查询条件,结果应为第七条记录.
也就是:select id from @t where id>1 and do=1 and name=a
结果id=7,是有数据的. )
sql执行的是先去执行in后的子查询select id from @t where id>a.id and do=a.do and name=a.name,那时候就不存在什么主查询的指针了,所以你的子查询返回的是空集,然后主查询自然不可能拿到任何比较的数据了.当然也返回不了什么东西了.
Top
12 楼goocity(健)回复于 2006-06-05 16:17:01 得分 0
exists返回一个boolean类型的值。
前者
select * from @t a where exists(select 1 from @t where id>a.id and do=a.do and name=a.name)
是因为子查询返回真,所以就把@t的所有结果都查出来了。
后者
select * from @t a where id in (select id from @t where id>a.id and do=a.do and name=a.name)
子查询返回的是记录集。可能你这个记录集里。没有数据,所以才查不出来。Top
13 楼slsunya(新浪子)回复于 2006-06-05 20:42:10 得分 0
两个语句作用大不一样。
前者要找出:do,name值相同,而id最小的记录。
后者要找出:do,name值相同,而id却比本身id值大的记录。试问有哪条记录的id会比其自己的大呢?所以,只能最多求出比自己id相等的记录。若改为 id>a.id则找出的是所有的记录。因此该语句天生有缺陷。Top
14 楼slsunya(新浪子)回复于 2006-06-05 20:43:35 得分 0
两个语句作用大不一样。
前者要找出:do,name值相同,而id最小的记录。
后者要找出:do,name值相同,而id却比本身id值大的记录。试问有哪条记录的id会比其自己的大呢?所以,只能最多求出比自己id相等的记录。若改为 id=a.id则找出的是所有的记录。因此该语句天生有缺陷。
Top




