--经常看到有人问not exists的用法,SQL联机帮助举例子也是不能说明问题,我在这里班门弄斧一下,解释一下,如果各位老大看到后不要笑话,如果有更好的解释请各位老大指正!
--借用前几天看到的一帖做例子:
--表@tb1,3个字段,终端号、记录时间、卡号,找出每个终端最新的打卡记录:--示例:
declare @tb1 table (termNum varchar(10),recordTime datetime,cardNum varchar(10))
insert into @tb1
select 1,'20090201','100001'union all
select 1,'20090202','100002'union all
select 1,'20090203','100007'union all
select 2,'20090204','100007'union all
select 2,'20090205','100001'union all
select 2,'20090206','100002'union all
select 2,'20090207','100001'union all
select 3,'20090208','100013'union all
select 3,'20090209','100007'--SQL语句
select t.* from @tb1 t where not exists(select 1 from @tb1 where termNum=t.termNum and recordTime>t.recordTime)--返回结果:
/*
termNum recordTime              cardNum
1 2009-02-03 00:00:00.000 100007
2 2009-02-07 00:00:00.000 100001
3 2009-02-09 00:00:00.000 100007
*/--解释原因:
--当()里无满足条件的记录时,布尔值为False,才返回Select的记录。具体为:
--(1)当t.*里面“记录时间”不取最大值时,()内总能找到“记录时间”比t集合里面大的记录,如1,'20090203','100007'这条,()里的集合有记录,布尔值为true,这时就不返回Select的记录;
--(2)当t.*里面“记录时间”取最大值时,()内无满足条件的记录,即找不到“记录时间”比t集合里面更大的记录了,即()里的集合没有记录,布尔值为False,这时就返回Select的记录。

解决方案 »

  1.   

    可是我看的书是这样说的:从集合的角度看,就是求主查询与子查询的差集,即从主查询的数据集中减去子查询的数据。
    所以我一直都是这样认为的:当recordTime>t.recordTime,不就取有最大值了吗,not exists就是不返回,也就是说,不返回最大值了。。晕啊!
    照楼主这样的意思,就是没找到最大值就不返回么?
      

  2.   

    TO 12楼:
    你那样想就钻牛角尖了。
    可以把表查询看作是一个循环,循环的次数就是表记录数,循环体就是一个是否返回记录的判断过程,如果not exists()的()里是False,就返回,是True就不返回
      

  3.   

    理解了这点,就不难理解select 1是什么意思了,这个select 1的写法只是最简单的写法,可以是Select 'abc' Select '张三'等,重要的是不管怎么写不影响()里的布尔值判断方法。