表tab1中有如下两条记录, 
      字段A          字段B 
记录1:0121(大类)    60.00 
记录2:0121001(小类)  70.00 表tab2中,有一字段c,有可能是4位,有可能是6位,与tab1中的A字段是相等的,现在的要求是先要满足6位的,如果6位的记录没有,就找4位的。也就是说,如果 where tab2.c=tab1.A 没有找到匹配的记录,就用where substr(tab2.c,0,4)=tab1.A 也就是先找小类,如果小类不满足,就继续找大类,要求这个条件写在一个SQL语句里。 
也就是像这样的: 
where (tab2.c=tab1.A or substr(tab2.c,1,4)=tab1.A 
但是,上面这样会把两条记录都查出来,我要的结果是如果tab2.c=tab1.A满足的话,就取出70.00,不再执行substr(tab2.c,1,4)=tab1.A了。 谢谢

解决方案 »

  1.   

    select * from tab1 a ,tab2  where tab1.a=case when exists (select 1 from tab2 where c=a.a) then tab2.c else substr(tab2.c,1,4) end;
      

  2.   

    --使用decode函数,试一下:select * from tab1,tab2 where 1 = decode(tab1.a,tab2.c,1,substr(tab2.c,1,4),1,0);
      

  3.   

    -- TRY IT ..
    SQL> SELECT * FROM TABLE1;A                             B
    -------------------- ----------
    0121                      60.00
    012101                    70.00
    0122                     110.00
    012301                   230.00
    012303                    45.00
    0123                      80.006 rows selectedSQL> SELECT * FROM TABLE2;C
    --------------------
    012101
    0122
    0123SQL> SELECT A, B
      2    FROM (SELECT T1.*,
      3                 ROW_NUMBER() OVER(PARTITION BY SUBSTR(T1.A, 0, 4) ORDER BY T1.A DESC) RN
      4            FROM TABLE1 T1) TT
      5   WHERE EXISTS (SELECT 1
      6            FROM TABLE2 T2
      7           WHERE DECODE(T2.C, TT.A, T2.C, SUBSTR(TT.A, 0, 4)) =
      8                 DECODE(T2.C, TT.A, T2.C, SUBSTR(T2.C, 0, 4)))
      9     AND RN = 1;A                             B
    -------------------- ----------
    012101                    70.00
    0122                     110.00
    012303                    45.00
      

  4.   

    表1:
    序号 字段A     字段B 
    1    0121     60.00
    2    0121001  70.00现在表2里有一字段C,该字段同表1的A字段样,有可能是4位,有可能是6位,现在两表结合查询,条件是要首先满足小类,再满足大类(0121是大类,0121001是小类)假设:现在表2里的字段C=0121001如果现在表1中只有第二条记录,现在表2中的字段C=0121001,表1的第二条记录刚好匹配,应取出70.00
    如果现在表1中只有第一条记录,那就是substr(表2.C,1,4)=表1.A),就应取出60.00
     
    问题是:如果表1中这两条记录同时存在,如何先满足小类,再满足大类?(如果两条记录同时存在,应得到70.00)我看了一下楼上的好像都有道理,但还没验证~~~
      

  5.   

    --改了一下:select a,b from tab1 
           where length(a)=(select max(length(m.a)) 
                                   from tab1 m,tab2 n 
                                   where 1 = decode(m.a,
                                                    n.c,
                                                    1,
                                                    substr(n.c,1,4),
                                                    1,
                                                    0
                                                    )
                            )
    ;
     
      

  6.   

    我今天试了一下1楼、2楼提供的方法,结果不对。
    因为我那是两个表结合查询,如果不加上面的这个判断条件,两表结合后的结果集如下:
    序号 字段1      字段2
    1    0121     60.00
    2    0121001  70.00用了1楼和2楼的方法,查询结果是一样的。
    因为表2中的字段C=‘0121001’,无论是decode还是case,都是在其自身行中进行判断,当游标走到第一条记录时,会用到查询中的substr,走到第二条记录时,是直接相等。所以两条记录同时查出来了。现在表2.C=‘0121001’,应该取出70我的实际程序中是4个表关联查询,是一个循环(放在for rec里面的),每个表的主键多达5个以上,而且还有其它条件的判断也较复杂。4楼的用到了排序,虽然结果是预期输出的,但使得整个程序变得非常庞杂,都理不清了。实在没有办法了,今天我把4个表拆开了,选了两个表作基表放在最外层的循环里,另两个表放在循环内部,这样问题倒是解决了,但整个程序看起来似乎重复的代码较多(因为代码本来就较长,那两个表的判断我先是用的"=",如果no_data_found,就用"substr")。6楼的我明天再试一下。感谢楼上各位的相助,如果还有其它方法,也请提出来,我再去试一下,力求找到一个最好的解决方案,谢谢各位啦~~~
      

  7.   

    不是结果都出来了,为什么还理不清呢?呵呵。如果NEED帮忙,需要您提供更多的资料。
      

  8.   

    试试我这个方法,就是先让oracle找出2条数据,然后再取一条
    scott@ORA1> select * from tab1;A                    F2
    -------------------- --------------------
    0121                 60
    0121001              70scott@ORA1> select * from tab2;C
    --------------------
    0121001scott@ORA1> SELECT *
      2    FROM (
      3   select tab1.*
      4     ,tab2.*
      5     ,row_number() over(partition by tab2.C order by length(tab1.A) DESC) rn
      6     from tab1, tab2
      7    where tab1.A = tab2.C
      8       or tab1.A = substr(tab2.c,1,4)
      9   )
     10   WHERE rn = 1;A                    F2                   C                            RN
    -------------------- -------------------- -------------------- ----------
    0121001              70                   0121001                       1
      

  9.   

    select max(A) from tab1 a
    where exists
      (
         select * from tab2 b
         where a.A=b.C or substr(b.C,1,4)=a.A
      )
    group by substr(A,1,4)
      

  10.   

    按前四位来进行排序,取最长的那个SQL> select * from test;A          B
    ---------- ----------
    0121       60.00
    012101     90.00
    0123       65.00
    0125       70.00
    012504     68.00SQL> select a, b
      2    from (select a,
      3                 b,
      4                 row_number() over(partition by substr(a, 1, 4) order by a desc) rn
      5            from test)
      6   where rn = 1;A          B
    ---------- ----------
    012101     90.00
    0123       65.00
    012504     68.00
      

  11.   


    SQL>  select * from tab;A                 B
    -------- ----------
    0121          60.00
    012101        70.00
    0122         110.00
    0124         230.00
    012303        45.00
    0123          80.006 rows selectedSQL>  select * from tab2;C
    ------
    012101
    0122
    012302
    0121SQL>  select t.f1, t.f2
      2     from (select m.a f1,
      3                  m.b f2,
      4                  n.c f3,
      5                  row_number() over(partition by m.a order by length(n.c) desc) f4
      6             from tab m, tab2 n
      7            where 1 = decode(m.a, n.c, 1, substr(n.c, 1, 4), 1, 0)) t
      8    where t.f4 = 1;F1               F2
    -------- ----------
    0121          60.00
    012101        70.00
    0122         110.00
    0123          80.00SQL>