oracle SQL select / join with many-to-one和nulls

时间:2015-03-26 15:26:48

标签: sql oracle

我在制作一个返回我寻求的结果的Oracle SQL查询时遇到了麻烦。可能我想做的事情是不可能的。

对于表1中的给定代码,如果代码存在于表2中,并且任何标志是" 1",则状态应为" 1"在查询结果中。否则,状态应为" 0"。如果表2中的代码根本不存在,那么状态应该为空。

tab1
------------
id,code
------------
1,ABC
2,DEF
3,GHI
4,JKL
5,MNO
6,PQR
7,STU

tab2
------------
id,code,flag
------------
1,ABC,0
2,ABC,0
3,DEF,1
4,DEF,1
5,GHI,0
6,GHI,1
7,JKL,1
8,JKL,0
9,MNO,0
10,PQR,1

(query?)

result
------------
id,code,status
------------
1,ABC,0
2,DEF,1
3,GHI,1
4,JKL,1
5,MNO,0
6,PQR,1
7,STU,null

到目前为止,我能够提出的唯一问题是,这在状态列中没有给出正确的结果......

select tab1.*, (select * from (
select flag from tab2 where tab2.code = code order by flag desc)
where rownum <=1) as status from tab1;

...状态总是&#34; 1&#34;,这是不正确的。

我认为不是使用order by并选择第一个结果,而是可以改为计算&#34; 1&#34;每个代码的标志,但我不确定这是否有效。

6 个答案:

答案 0 :(得分:1)

我的第一个倾向是使用子选择:

select t1.*,
       (select max(t2.flag)
        from table2 t2
        where t2.code = t1.code
       ) as t2flag
from table1 t1;

您也可以将此短语标记为left join并使用聚合:

select t1.*, t2.flag
       (select max(t2.flag)
        from table2 t2
        where t2.code = t1.code
       ) as t2flag
from table1 t1 left join
     (select t2.code, max(t2.flag) as flag
      from table2 t2
      group by t2.code
     ) t2
     on t2.code = t1.code;

这两种方法都假定标志为0或1,如您的问题所示。

答案 1 :(得分:0)

我使用LEFT JOIN:

select t1.id, max(t1.code) code, max(t2.flag) status
from table1 t1
left join table2 t2 on t1.code=t2.code
group by t1.id

答案 2 :(得分:0)

假设0和1是唯一的两个标志,那么类似于:

with tab1 as (select 1 id, 'ABC' code from dual union all
              select 2 id, 'DEF' code from dual union all
              select 3 id, 'GHI' code from dual union all
              select 4 id, 'JKL' code from dual union all
              select 5 id, 'MNO' code from dual union all
              select 6 id, 'PQR' code from dual union all
              select 7 id, 'STU' code from dual),
     tab2 as (select 1 id, 'ABC' code, 0 flag from dual union all
              select 2 id, 'ABC' code, 0 flag from dual union all
              select 3 id, 'DEF' code, 1 flag from dual union all
              select 4 id, 'DEF' code, 1 flag from dual union all
              select 5 id, 'GHI' code, 0 flag from dual union all
              select 6 id, 'GHI' code, 1 flag from dual union all
              select 7 id, 'JKL' code, 1 flag from dual union all
              select 8 id, 'JKL' code, 0 flag from dual union all
              select 9 id, 'MNO' code, 0 flag from dual union all
              select 10 id, 'PQR' code, 1 flag from dual)
select t1.id,
       t1.code,
       t2.flag status
from   tab1 t1
       left join (select code,
                         max(flag) flag
                  from   tab2
                  group by code) t2
         on (t1.code = t2.code);

        ID CODE     STATUS
---------- ---- ----------
         5 MNO           0
         6 PQR           1
         2 DEF           1
         1 ABC           0
         3 GHI           1
         4 JKL           1
         7 STU            

答案 3 :(得分:0)

也许我错过了什么,但它似乎就像这样简单:

select tab1.id, tab1.code, max(tab2.flag) status
from tab1
left join tab2 on tab1.code = tab2.code
group by tab1.id, tab1.code
order by tab1.id;

sample SQL Fiddle给出了所需的结果:

| id | code | status |
|----|------|--------|
|  1 |  ABC |      0 |
|  2 |  DEF |      1 |
|  3 |  GHI |      1 |
|  4 |  JKL |      1 |
|  5 |  MNO |      0 |
|  6 |  PQR |      1 |
|  7 |  STU | (null) |

答案 4 :(得分:0)

SELECT ID,
  CODE,
  MAX( STATUS)
FROM
  (SELECT DISTINCT T1.ID,
    T1.CODE,
    FLAG AS STATUS
  FROM T1
  LEFT JOIN T2
  ON T1.CODE = T2.CODE
  )
GROUP BY ID,
  CODE;

答案 5 :(得分:0)

这会在您提出结果时给出结果:

SELECT tab1.id,tab1.code,max(tab2.flag) as Status
FROM tab1 LEFT JOIN tab2
ON tab1.code=tab2.code
GROUP BY tab2.code
ORDER BY tab1.id;