CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  MS-SQL Server >  疑难问题

sql语句中关键字Exists 与 in 的区别,看下列实例

楼主ll_e_mail()2006-06-04 08:06:55 在 MS-SQL Server / 疑难问题 提问

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

相关问题

关键词

得分解答快速导航

  • 帖主:ll_e_mail
  • billpu

相关链接

  • SQL Server类图书

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo