有两张表如下 主键字段是MC
表1:table1
MC字段    DZ字段
---------------
李某       XX地区
张某       湖南地区
陈某       广东地区
刘某       上海表2:table2
MC字段      YXBZ字段
--------------------
李某          Y
刘某          N
陈某          N
我需要查询出表2中 YXBZ字段为N的 DZ信息
select * from table1 where MC not in (select MC from table2 where YXBZ='N');
这样可以用NOT IN 实现问题是 我表里面存在大量的数据这样查询效率实在太低,感觉用NOT exists 也差不多 有没有办法用个存储过程实现!
希望那位大侠能写去一个完整的存储过程来看看,对存储过程不是很了解
    

解决方案 »

  1.   

    select * from table1 a 
    where  not exists (select 1 from table2 bwhere YXBZ='N' where a.MC=b.MC);
      

  2.   


    select * from table1 a 
    where  not exists (select 1 from table2 b where YXBZ='N' where a.MC=b.MC);
      

  3.   


    --你到底是要查询表2中YXBZ为N还是不为N的啊?
    --为N用exists 不为N 用not exists
    select * from table1 a where exists (select 1 from table2 where YXBZ='N' AND MC=a.MC);
      

  4.   

    我感觉在有存在不存在的情况下,最好是在exists的查询子句中添加上一个rownum=1的这样一个条件 ,因为只要查到一个数据就知道有没有了
      

  5.   


    楼主意思表达不清楚,说得是要找YXBZ为N的果实现的就不是。
      

  6.   

    我上面写了 是表2中 YXBZ 为N的嘛..
      

  7.   

    谢谢您的回答 我用not exists 测试过感觉效率也不是很好.这个能用存储过程实现吗??
      

  8.   

    好了 该问题解决了 呵呵 谢谢大侠们..
    拿来分享下 嘿嘿是使用的一个简单的存储过程
    create or replace procedure P_table(
    --输入参数自定义
    --输出参数 rs
    rs OUT SYS_REFCURSOR
    ) is
    begin
    delete tmp_table;
    --------方案1 将主表满足条件的字段放到一个临时表中
    insert into tmp_table
      (MC)
      select T.MC
        from table1 T;
    ---如果数据量大还可以跟条件
    -----删除等于Y 的 临时表数据     
    delete tmp_table tmp where tmp.MC in (select MC from table2 where yxbz='Y');
    ---将其余的数据查询出来
    open rs FOR 
    select * from table1 t,tmp_table tmp where t.MC= tmp.MC;
    end P_ table;
      

  9.   

    如果b表数据量较少
    可以用两表关联查询
    查看解释计划
    是否使用 nested_loops
    并且b表 YXBZ字段加索引
    a表 MC字段加索引
    若没有用nested_loops则可强制使用/*+use_nl(table1,table2)*/
    如有不对 望高手指点
      

  10.   

    not exists 替代 not in
      

  11.   

    但是如果 过滤的值为几个常量的话 。貌似not in效率可能更好