问题描述:

ID(Number)     SQ(varchar2型)       OtherCol(varchar2型)
1               H                     This is H
2               B,C                   There are B and C
3               C                     This is C
4               D                     This is D
5               G,A                   I like G and A
6               D,C                   I hate D and C
7               I                     It is me查询目的:
想查询出含有A 或者 B 或者 C的记录。也就是说想得到结果
ID(Number)     SQ(varchar2型)       OtherCol(varchar2型)
2               B,C                   There are B and C
3               C                     This is C
5               G,A                   I like G and A[题外:实际的项目中的此表相当大,大概10亿条以上是普通的,最大可达到10000亿条记录。]希望各位写SQL语句的高手给个idea,如何通过一条SQL就能实现我的查询目的,在此不胜感激!

解决方案 »

  1.   

    直接在WHERE里加条件用
    sq LIKE '%a%'
    or sq LIKE '%b%'
    or sq LIKE '%c%'不就行了,不过这么多数据,肯定会慢,一般这么多数据应该会分成多张表的吧
      

  2.   

    select * from 表 where (',' + SQ + ',' like '%,A,%' or ',' + SQ + ',' like '%,B,%' and ',' + SQ + ',' like '%,C,%')这样就可以楼主应该还要把ID为6 D,C也查出来吧
      

  3.   

    谢谢hebo2005问题描述部全面,查询条件中的A, B, C可能会有200到300个,想象一下,一条SQL语句中有200个 sq like '%XXX%' 并且以or组合在一起的话,会是什么效率啊。非常感谢hebo2005。
      

  4.   

    to wuyujian:
    确实ID0=6的记录应该也在结果里面。真是个仔细的人,表扬下,这样的员工老板肯定稀饭的很!不过,就像我在3搂补充的一样,不能考虑用like 加 or 的方式来实现。
      

  5.   

    主要你这张表里ABC出现的位置没什么规律,有规律的话好做点
      

  6.   

    楼主,不妨试试where charindex('a',SQ) or charindex('b',SQ) or charindex('c',SQ)这样做也一样能查出来的,数据多肯定效率是降低了,可以加个全主索引,看可不可以使效率高些
      

  7.   

    对不起,charindex('a',SQ) 后面要加大于0
      

  8.   

    是啊,确实没有什么规律。如果表中的数据没有那么多,那么也没有什么问题。数据太多了,每做一条SQL语句,我都不得不考虑性能,考虑有没有更好的方法。
    在测试环境中测试了一下,测试环境中才6000万条数据,很多平常的SQL语句已经非常慢了。我对DB这一块虽然不精通,但是接触6年了,这一次最头疼,问题简单,但各种各样的SQL都首先被自己推翻了,无比痛苦中。
      

  9.   


    试试这个
    drop table a;
    create table a
    (
     id number,
     sq char(10)
    );insert into a
    select 1,'A,C' from dual
    union all
    select 1,'D,E' from dual
    union all
    select 1,'1' from dual
    union all
    select 2,'B,A' from dual
    union all
    select 2,'4,5' from dual
    union all
    select 2,'C,1' from dual;SQL> select * from a;        IDSQ
    --------------------
             1A,C
             1D,E
             11
             2B,A
             24,5
             2C,1已选择6行。select * from a
    where instr(sq,'A',1,1)>0 or 
          instr(sq,'B',1,1)>0 or
          instr(sq,'C',1,1)>0 ;        IDSQ
    ------------------
             1A,C
             2B,A
             2C,1
      

  10.   

    其实不妨从数据结构上考虑下,加个字段标注下本条纪录是否包含A,B,C三个字符(假如是固定要查这三个话)
    这样的话也第一次慢,后面就会快了
      

  11.   


    select id,sq
    from
    (
       select rowid,id,sq,
         (instr(sq,'A',1,1)+instr(sq,'B',1,1)+instr(sq,'C',1,1)) as jj
       from a
    ) b
    where b.jj>0;
    还有这个,你自已试吧,或许有用
      

  12.   

    表中index是有的,不过不是这个列。加索引是个非常大的事情,加了索引写数据的速度相应会降低,并且加一个索引占用硬件的空间也就大了,相应的产品的成本就高了。
    看似一个简单的增加索引,但是牵涉到很多方面。当初曾经为了申请加一个索引,花了一个星期测试,写申请报告,从写性能对比,读性能对比,占用空间大小对比,到最后成本。唉~~~ 那种事情不想再干第二次,不过即使再作报告,估计也不能审批下来。绝了再次加index的念头了。
      

  13.   

    其他的办法真的没有了么?问题描述:

    ID(Number)     SQ(varchar2型)       OtherCol(varchar2型)
    1               H                     This is H
    2               B,C                   There are B and C
    3               C                     This is C
    4               D                     This is D
    5               G,A                   I like G and A
    6               A,D,C                 I hate D and C
    7               I                     It is me
    实际的项目中的此表记录相当多,大概10亿条以上是普通的,最大可达到10000亿条记录。
    此表的SQ列没有索引(其他的列有),不可以增加索引或增加新列什么的。查询目的:
    想查询出SQ列中含有A 或者 B 或者 C的记录。
    (实际的项目里面不止A,B,C之类的三个,会达到200到300个左右)也就是说想得到结果
    ID(Number)     SQ(varchar2型)       OtherCol(varchar2型)
    2               B,C                   There are B and C
    3               C                     This is C
    5               G,A                   I like G and A
    6               A,D,C                 I hate D and C希望各位写SQL语句的高手给个idea,如何查询,在此不胜感激! 
      

  14.   


    select id,sq
    from
    (
       select rowid,id,sq,
         (instr(sq,'A',1,1)+instr(sq,'B',1,1)+instr(sq,'C',1,1)) as jj
       from a
    ) b
    where b.jj>0;
    这种方法,你不认为是比效合理的吗????????????????????????
      

  15.   


    如果A,B,C不是特别的多,你感觉下面这方法可以否
    select max(a.id),max(a.sq)
    from a,
    (
          select substr(tt.str,
                      instr(','||tt.str||',',',',1,rn),
                      instr(','||tt.str||',',',',1,rn+1)-instr(','||tt.str||',',',',1,rn)-1) as str_new
          from (select   'A,B,C'   str   from   dual)  tt,
               (
               select rownum rn from all_objects where rownum <= 3
              )
         where instr(','||tt.str||',',',',1,rn+1) > 0
    ) b
    where instr(a.sq,b.str_new,1,1)>0 
    group by  a.id,a.sq;查询条件中的A,B,C可能会有200到300个,可否考虑新建表B,存查询条件,如'A,B,C'
     或
       A
       B
       C
    刚才始没注意有:"查询条件中的A,   B,   C可能会有200到300个"这句话
      

  16.   

    to wdswcy:
    真的太感谢你了,即使我的问题的不到解决我在一周以内肯定也会结贴的。
    到时候会给分哦,喜欢有passion的同学。言归正传,谈技术。
    我曾经想过建一张临时表,存放如A,B,C之类的值,但是那仅仅也只能是使SQL语句看上去简洁一点而已,实际上性能上还是比较差的。这种方法,根据测试结果,在从7000万条数据的测试条件下select出135万条的查询需要执行27秒左右。如果数据达到1亿条以上,那就跟慢了。
    说明一下,测试硬件环境还是比较好的,IBM最新服务器(小型机)。唉~~~ 如果实在还是要用临时表这个东东的话也真的是没有办法了,到时候只能在界面上跟用户说:您稍等啊,先去喝杯咖啡提提神,然后再来看结果,否则我不能保证您会不会因为等的不耐烦了砸了显示器。
      

  17.   

    有个思路,但已经不是从SQL的角度解决了 .
    是否可以考虑分批显示 !
    先判断单字符的数据里是否包括A\B\C,并显示结果.
    然后再处理非单字符的数据,这样以来,客户已经可以看到一些数据了.
    后台你再继续处理,并陆续显示结果!
    一个思路,希望对您有帮助!
      

  18.   


    select * from 表名 where patindex('%[A B C]%',SQ)>0
      

  19.   

    ORACLE没patindex函数的在数据量到到一定程度,小问题就会成大问题。