select distinct mbrid,dos from fo05 where 
(dx1 in('40201', '40211', '40291', '40401', '40411',  '40491','4280', '4281', '42820','42821','42822','42823',' 42840','42841','42842','42843')
or dx2 in('40201', '40211', '40291', '40401', '40411',  '40491','4280', '4281', '42820','42821','42822','42823',' 42840','42841','42842','42843')
or dx3 in('40201', '40211', '40291', '40401', '40411',  '40491','4280', '4281', '42820','42821','42822','42823',' 42840','42841','42842','42843')
or dx4 in('40201', '40211', '40291', '40401', '40411',  '40491','4280', '4281', '42820','42821','42822','42823',' 42840','42841','42842','42843')
or dx5 in('40201', '40211', '40291', '40401', '40411',  '40491','4280', '4281', '42820','42821','42822','42823',' 42840','42841','42842','42843')
or dx6 in('40201', '40211', '40291', '40401', '40411',  '40491','4280', '4281', '42820','42821','42822','42823',' 42840','42841','42842','42843')
or dx7 in('40201', '40211', '40291', '40401', '40411',  '40491','4280', '4281', '42820','42821','42822','42823',' 42840','42841','42842','42843')
or dx8 in('40201', '40211', '40291', '40401', '40411',  '40491','4280', '4281', '42820','42821','42822','42823',' 42840','42841','42842','42843')
or dx9 in('40201', '40211', '40291', '40401', '40411',  '40491','4280', '4281', '42820','42821','42822','42823',' 42840','42841','42842','42843')) 
and ((((cpt between '99201' and '99205') or (cpt between '99211' and '99215') or (cpt between '99241' and '99245') or (cpt between '99271' and '99275')
or (cpt between '99301' and '99313') or (cpt between '99315' and '99316') or (cpt between '99318' and '99337') or (cpt between '99341' and '99350')
or (cpt between '99354' and '99355') or (cpt between '99381' and '99387') or (cpt between '99391' and '99397') or (cpt between '99401' and '99429')
or (cpt= '99450') or (cpt between '99455' and '99456'))
or ((cpt1 between '99201' and '99205') or (cpt1 between '99211' and '99215') or (cpt1 between '99241' and '99245') or (cpt1 between '99271' and '99275')
or (cpt1 between '99301' and '99313') or (cpt1 between '99315' and '99316') or (cpt1 between '99318' and '99337') or (cpt1 between '99341' and '99350')
or (cpt1 between '99354' and '99355') or (cpt1 between '99381' and '99387') or (cpt1 between '99391' and '99397') or (cpt1 between '99401' and '99429')
or (cpt1= '99450') or (cpt1 between '99455' and '99456'))
or ((cpt2 between '99201' and '99205') or (cpt2 between '99211' and '99215') or (cpt2 between '99241' and '99245') or (cpt2 between '99271' and '99275')
or (cpt2 between '99301' and '99313') or (cpt2 between '99315' and '99316') or (cpt2 between '99318' and '99337') or (cpt2 between '99341' and '99350')
or (cpt2 between '99354' and '99355') or (cpt2 between '99381' and '99387') or (cpt2 between '99391' and '99397') or (cpt2 between '99401' and '99429')
or (cpt2= '99450') or (cpt2 between '99455' and '99456'))
or ((cpt3 between '99201' and '99205') or (cpt3 between '99211' and '99215') or (cpt3 between '99241' and '99245') or (cpt3 between '99271' and '99275')
or (cpt3 between '99301' and '99313') or (cpt3 between '99315' and '99316') or (cpt3 between '99318' and '99337') or (cpt3 between '99341' and '99350')
or (cpt3 between '99354' and '99355') or (cpt3 between '99381' and '99387') or (cpt3 between '99391' and '99397') or (cpt3 between '99401' and '99429')
or (cpt3= '99450') or (cpt3 between '99455' and '99456'))
or ((cpt4 between '99201' and '99205') or (cpt4 between '99211' and '99215') or (cpt4 between '99241' and '99245') or (cpt4 between '99271' and '99275')
or (cpt4 between '99301' and '99313') or (cpt4 between '99315' and '99316') or (cpt4 between '99318' and '99337') or (cpt4 between '99341' and '99350')
or (cpt4 between '99354' and '99355') or (cpt4 between '99381' and '99387') or (cpt4 between '99391' and '99397') or (cpt4 between '99401' and '99429')
or (cpt4= '99450') or (cpt4 between '99455' and '99456'))
or ((cpt5 between '99201' and '99205') or (cpt5 between '99211' and '99215') or (cpt5 between '99241' and '99245') or (cpt5 between '99271' and '99275')
or (cpt5 between '99301' and '99313') or (cpt5 between '99315' and '99316') or (cpt5 between '99318' and '99337') or (cpt5 between '99341' and '99350')
or (cpt5 between '99354' and '99355') or (cpt5 between '99381' and '99387') or (cpt5 between '99391' and '99397') or (cpt5 between '99401' and '99429')
or (cpt5= '99450') or (cpt5 between '99455' and '99456'))
or ((cpt6 between '99201' and '99205') or (cpt6 between '99211' and '99215') or (cpt6 between '99241' and '99245') or (cpt6 between '99271' and '99275')
or (cpt6 between '99301' and '99313') or (cpt6 between '99315' and '99316') or (cpt6 between '99318' and '99337') or (cpt6 between '99341' and '99350')
or (cpt6 between '99354' and '99355') or (cpt6 between '99381' and '99387') or (cpt6 between '99391' and '99397') or (cpt6 between '99401' and '99429')
or (cpt6= '99450') or (cpt6 between '99455' and '99456'))
or ((cpt7 between '99201' and '99205') or (cpt7 between '99211' and '99215') or (cpt7 between '99241' and '99245') or (cpt7 between '99271' and '99275')
or (cpt7 between '99301' and '99313') or (cpt7 between '99315' and '99316') or (cpt7 between '99318' and '99337') or (cpt7 between '99341' and '99350')
or (cpt7 between '99354' and '99355') or (cpt7 between '99381' and '99387') or (cpt7 between '99391' and '99397') or (cpt7 between '99401' and '99429')
or (cpt7= '99450') or (cpt7 between '99455' and '99456'))
or ((cpt8 between '99201' and '99205') or (cpt8 between '99211' and '99215') or (cpt8 between '99241' and '99245') or (cpt8 between '99271' and '99275')
or (cpt8 between '99301' and '99313') or (cpt8 between '99315' and '99316') or (cpt8 between '99318' and '99337') or (cpt8 between '99341' and '99350')
or (cpt8 between '99354' and '99355') or (cpt8 between '99381' and '99387') or (cpt8 between '99391' and '99397') or (cpt8 between '99401' and '99429')
or (cpt8= '99450') or (cpt8 between '99455' and '99456'))
or ((cpt9 between '99201' and '99205') or (cpt9 between '99211' and '99215') or (cpt9 between '99241' and '99245') or (cpt9 between '99271' and '99275')
or (cpt9 between '99301' and '99313') or (cpt9 between '99315' and '99316') or (cpt9 between '99318' and '99337') or (cpt9 between '99341' and '99350')
or (cpt9 between '99354' and '99355') or (cpt9 between '99381' and '99387') or (cpt9 between '99391' and '99397') or (cpt9 between '99401' and '99429')
or (cpt9= '99450') or (cpt9 between '99455' and '99456')))
or (((rev between '0500' and '0529') or (rev between '0570' and '0599') or (rev between '0770' and '0779') or (rev between '0820' and '0859') 
or (rev between '0982' and '0983') or (rev = '0882')
or (rev1 between '0500' and '0529') or (rev1 between '0570' and '0599') or (rev1 between '0770' and '0779') or (rev1 between '0820' and '0859') 
or (rev1 between '0982' and '0983') or (rev1 = '0882')
or (rev2 between '0500' and '0529') or (rev2 between '0570' and '0599') or (rev2 between '0770' and '0779') or (rev2 between '0820' and '0859') 
or (rev2 between '0982' and '0983') or (rev2 = '0882')
or (rev3 between '0500' and '0529') or (rev3 between '0570' and '0599') or (rev3 between '0770' and '0779') or (rev3 between '0820' and '0859') 
or (rev3 between '0982' and '0983') or (rev3 = '0882')
or (rev4 between '0500' and '0529') or (rev4 between '0570' and '0599') or (rev4 between '0770' and '0779') or (rev4 between '0820' and '0859') 
or (rev4 between '0982' and '0983') or (rev4 = '0882')
or (rev5 between '0500' and '0529') or (rev5 between '0570' and '0599') or (rev5 between '0770' and '0779') or (rev5 between '0820' and '0859') 
or (rev5 between '0982' and '0983') or (rev5 = '0882')
or (rev6 between '0500' and '0529') or (rev6 between '0570' and '0599') or (rev6 between '0770' and '0779') or (rev6 between '0820' and '0859') 
or (rev6 between '0982' and '0983') or (rev6 = '0882')
or (rev7 between '0500' and '0529') or (rev7 between '0570' and '0599') or (rev7 between '0770' and '0779') or (rev7 between '0820' and '0859') 
or (rev7 between '0982' and '0983') or (rev7 = '0882')
or (rev8 between '0500' and '0529') or (rev8 between '0570' and '0599') or (rev8 between '0770' and '0779') or (rev8 between '0820' and '0859') 
or (rev8 between '0982' and '0983') or (rev8 = '0882')
or (rev9 between '0500' and '0529') or (rev9 between '0570' and '0599') or (rev9 between '0770' and '0779') or (rev9 between '0820' and '0859') 
or (rev9 between '0982' and '0983') or (rev9 = '0882')))) 
谁看看这个语句怎么能优化一下啊……  求助高手啊  谢谢了啊………………
数据量很大的数据库啊……  几百万的数据量

解决方案 »

  1.   

    楼主,建议你用存储过程实现。储过程实现逻辑清晰。容易调试。效率也高。这个sql太乱了。
      

  2.   

    select distinct mbrid, dos 
    from   fo05 
    where (dx1 in('40201', '40211', '40291', '40401', '40411',  '40491','4280', '4281', '42820','42821','42822','42823',' 42840','42841','42842','42843') 
           or dx2,3,4,5,6,7,8,9) 
    and ((      ((cpt between '99201' and '99205') 
              or (cpt between '99211' and '99215') 
              or (cpt between '99241' and '99245') 
              or (cpt between '99271' and '99275') 
              or (cpt between '99301' and '99313') 
              or (cpt between '99315' and '99316') 
              or (cpt between '99318' and '99337') 
              or (cpt between '99341' and '99350') 
              or (cpt between '99354' and '99355') 
              or (cpt between '99381' and '99387') 
              or (cpt between '99391' and '99397') 
              or (cpt between '99401' and '99429') 
              or (cpt = '99450') 
              or (cpt between '99455' and '99456') ) 
          or  (cpt1,2,3,4,5,6,7,8,9)
          or (rev between '0500' and '0529') or (rev between '0570' and '0599') or (rev between '0770' and '0779') or (rev between '0820' and '0859') 
            or (rev between '0982' and '0983') or (rev = '0882') 
          or rev1,2,3,4,5,6,7,8,9));格式了下让后面的人看的清楚些,这个没法了。
    或者
    select distinct mbrid, dos from (
    select mbrid, dos 
    from   fo05 
    where (dx1 in('40201', '40211', '40291', '40401', '40411',  '40491','4280', '4281', '42820','42821','42822','42823',' 42840','42841','42842','42843') 
    union all
    select mbrid, dos 
    from   fo05 
    where (dx2 in('40201', '40211', '40291', '40401', '40411',  '40491','4280', '4281', '42820','42821','42822','42823',' 42840','42841','42842','42843') 
    ..
    );
    用过程分步拆解可能好点
      

  3.   

    比如这段
     ((      ((cpt between '99201' and '99205') 
              or (cpt between '99211' and '99215') 
              or (cpt between '99241' and '99245') 
              or (cpt between '99271' and '99275') 
              or (cpt between '99301' and '99313') 
              or (cpt between '99315' and '99316') 
              or (cpt between '99318' and '99337') 
              or (cpt between '99341' and '99350') 
              or (cpt between '99354' and '99355') 
              or (cpt between '99381' and '99387') 
              or (cpt between '99391' and '99397') 
              or (cpt between '99401' and '99429') 
              or (cpt = '99450') 
              or (cpt between '99455' and '99456') ) 
          or  (cpt1,2,3,4,5,6,7,8,9)
    换成
    where exists(select 1 from(
      select '99201' a,'99205' b from dual union all
      select '99211' ,'99215'  from dual union all
      ...
      select '99455','99456' from dual)where fo05.cpt1 between a and b
      or fo05.cpt2 between a and b
      or...)这里的全部条件都能换成这种形式,能减少些代码量
      

  4.   

    类似条件分成3组
    以上面的写法就是3个exists
    楼主可以试试
    没想到更好的办法
      

  5.   

    想法大胆,不过好像与实际应用不符合,都看晕了好几回。
    平生第一次看见一个where条件后面有这么多条件的。
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      

  6.   

    wildwave
     
    (狂浪)   用了你的那种方法,代码是少了很多啊
    看起来也清晰,但是 速度却是降低了很多很多啊,为什么啊…… 我现在要求的就是执行的效率啊……
      

  7.   

    jiaruimin11
     
    (jiaruimin11)   在存储过程里面怎么实现啊……
      

  8.   

    谁写的这种SQL,佩服其耐心!
      

  9.   

    lz,以其帮你优化这个语句,不如教你方法:
    1、将这些代码值存入代码表,再在主表与代码表之间找逻辑关系;
    2、若条件太多时,应将条件归类,将能合并的条件通通合并
       比如:a > 1 and a>2 合并为a > 2
    3、实在无法简化时,就将不同的逻辑类做成视图或子表,这样更能直观表述你的逻辑
      

  10.   

    貌似可以优化,dx? in('40201', '40211', '40291', '40401', '40411',  '40491','4280', '4281', '42820','42821','42822','42823',' 42840','42841','42842','42843') 
    这一段可以改成Instr('40201,40211,40291,40401,40411,40491,4280,4281,42820,42821,42822,42823,42840,42841,42842,42843', dx?) > 0
    然后,在 fo05 表上建函数索引
    create inext fo05_dx1 on fo05 (instr(Instr('40201,40211,40291,40401,40411,40491,4280,4281,42820,42821,42822,42823,42840,42841,42842,42843', dx1) tablespace 索引表空间;
     
      

  11.   

    上面创索引的语句有问题,多了个Instr(:
    create inext fo05_dx1 on fo05 (Instr('40201,40211,40291,40401,40411,40491,4280,4281,42820,42821,42822,42823,42840,42841,42842,42843', dx1) tablespace 索引表空间; 另外:楼主
      类似cpt between '99201' and '99205'  99301-99205中的值是否有规律。
      

  12.   

    最好不要用or ,in , union (all) ,都不要用,把你要的搜索的条件,写成一个视图,然后表和视图做连接就行了!!这样是最快的,特别是数据海量的时候这种方法是比较好的选择!!!
      

  13.   


    create view  test_dx as select distinct mbrid,dos from fi05 where 
    (
    dx1 in('40201', '40211', '40291', '40401', '40411',  '40491','4280', '4281', '42820','42821','42822','42823',' 42840','42841','42842','42843')
    or dx2 in('40201', '40211', '40291', '40401', '40411',  '40491','4280', '4281', '42820','42821','42822','42823',' 42840','42841','42842','42843')
    or
    ..... 
    or dx9 in('40201', '40211', '40291', '40401', '40411',  '40491','4280', '4281', '42820','42821','42822','42823',' 42840','42841','42842','42843')
    ) create view test_cpt as select distinct mbrid,dos from fi05 where
    ((cpt between '99217' and '99220')  or (cpt between '99234' and '99236'))
        or ((cpt1 between '99217' and '99220')  or (cpt1 between '99234' and '99236'))
         ....
        or ((cpt9 between '99217' and '99220')  or (cpt9 between '99234' and '99236'))
        
        
    create view test_rev as select distinct mbrid,dos from fi05 where 
        ((rev between '0500' and '0529') or (rev between '0570' and '0599') or (rev between '0770' and '0779') or (rev between '0820' and '0859' )
        or (rev between '0982' and '0983') or (rev = '0882'))
        or((rev1 between '0500' and '0529') or (rev1 between '0570' and '0599') or (rev1 between '0770' and '0779') or (rev1 between '0820' and '0859') 
        or (rev1 between '0982' and '0983') or (rev1 = '0882'))
        ......    
        or ((rev9 between '0500' and '0529') or (rev9 between '0570' and '0599') or (rev9 between '0770' and '0779') or (rev9 between '0820' and '0859')
        or (rev9 between '0982' and '0983') or (rev9 = '0882'))
        
     
     select a.mbrid from fi05 a,test_dx b,test_cpt c,test_rev d where a.mbrid = b.mbrid and (a.mbrid = c.mbrid or a.mbrid = d.mbrid)
    是这样嘛?