有两张表:tmp_dzfwq、tmp_serarea都有地址id(stid)这个字段
select distinct stid from tmp_dzfwq    --581条记录
select distinct stid from tmp_serarea  --1022条记录
两张表里有一部分stid值是相同的,我现在想找出在serarea表里有的stid,在dzfwq表里没有的stid:
select distinct stid from tmp_serarea s 
where exists(select 1 from tmp_dzfwq z where s.stid<>z.stid)   --1022条记录
这样的话居然还是把serarea表里的所有stid都查出来了;如果这样:
select distinct stid from tmp_serarea s 
where not exists(select 1 from tmp_dzfwq z where s.stid=z.stid)   --467条记录
为什么这样写跟上面的差别这么大?我觉得这两条语句要表达的意思是一样的啊!!还有要找出serarea表里有的stid,在dzfwq表里没有的stid下面的语句对不对?

解决方案 »

  1.   


    select distinct stid from tmp_serarea s
    where exists(select 1 from tmp_dzfwq z where s.stid<>z.stid) --1022条记录select distinct stid from tmp_serarea s
    where not exists(select 1 from tmp_dzfwq z where s.stid=z.stid) --467条记录
    sql1和sql2可不等价。
    sql1:表tmp_serarea每检索一条记录后,到表tmp_dzfwq判断,满足s.stid<>z.stid的时候(基本都满足),返回true.所以返回 1022了
      

  2.   

    比如  tmp_dzfwq  stid  1,2,3
    tmp_serarea   stid  1,2,3
    sql1:当tmp_dzfwq stid=1 select 2,3;当tmp_dzfwq stid=2 select 1,3;当tmp_dzfwq stid=3 select 1,2
     最后 1,2,3sql2:当tmp_dzfwq stid=1 select 无记录;tid=2 select 无记录;tid=3 select 无记录(因为tmp_serarea均存在)
    最后 无记录
      

  3.   


    select distinct stid from tmp_serarea s
    where exists(select 1 from tmp_dzfwq z where s.stid<>z.stid) --1022条记录select distinct stid from tmp_serarea s
    where not exists(select 1 from tmp_dzfwq z where s.stid=z.stid) --467条记录--举例:tmp_serarea 两条记录 1,2,tmp_dzfwq 一条记录 1,3
    --第一种写法: 对于 1 这个记录,存在 3 与他不等,而条件是exists 因此查出
    --第二中写法: 对于 1 这个记录,存在 1 与他相等,而条件是not exists 因此查不出。
      

  4.   

    那sql2的意思就是:表tmp_serarea每检索一条记录后,到表tmp_dzfwq判断,不满足s.stid=z.stid时,才返回值?
      

  5.   

    那sql2的意思就是:表tmp_serarea每检索一条记录后,到表tmp_dzfwq判断,满足s.stid=z.stid时,返回false,否则,true
      

  6.   

    还要注意id为null的情况,会影响结果的。
      

  7.   

    谢谢hudingchen!是不是可以这样理解:对于exists,当从serarea表里检索到一条记录后,就会拿这条记录的stid去dzfwq表里跟所有记录比对,当dzfwq表里存在一个stid跟s.stid不等的时候,就返回这条记录?对于not exists:当从serarea表里检索到一条记录后,拿这条记录的stid去dzfwq表里跟记录比对,只有当dzfwq表里所有的stid跟s.stid不等的时候,才返回这条记录?不知道这样理解对不对
      

  8.   

    看我3楼的回答,补充一点如果 tmp_dzfwq 只有一条记录,那么这两个sql是等价的。
      

  9.   

    楼主你再倒腾倒腾以下两句话,或许能增强你的理解!
    select distinct stid from tmp_serarea s
    where exists(select 1 from tmp_dzfwq z where s.stid=z.stid) select distinct stid from tmp_serarea s
    where not exists(select 1 from tmp_dzfwq z where s.stid<>z.stid)
      

  10.   

    嗯,倒腾了下:
    第一个是找出在两张表里都存在的stid
    第二个是找出serarea表里的stid,条件是在dzfwq表里找不到跟该stid不等的记录,结果当然是0感谢各位,终于理解了!!