ORACLE连接表以选择1行中的多个记录

时间:2015-08-25 14:59:37

标签: database oracle join

我有2张桌子

TableA :每个字段都有1条记录的主表格,名为 ID
TableB :可以包含名为 ID

的字段的多个记录

我想根据 TableA 中的 ID 选择所有内容,并在1行中选择 TableB 以获得最终结果

实施例

样本记录 来自 TableA

ID   Name Address
---  ---- ----------
1    Jack 123 blahST
2    John 234 blahAVE
321  Sam  2123 blahWay

来自 TableB

ID AccNO
-- -------------
1  12345
1  345345
1  443453
2  99999
3  88888
3  77777

最终结果应该像

Select TableA.ID,
       TableA.Name,
       TableA.Address,
       TableB.ID,
       TableB.AccNO1,
       TableB.AccNO2, --if it exist
       TableB.AccNO3, --if it exist
       TableB.AccNO4, --if it exist MAX
From TableA Full Outer Join TableB on TableB.ID = TableA.ID

TableA.ID  TableA.Name TableA.Address TableB.ID TableB.AccNO TableB.AccNO2 TableB.AccNo3,TableB.AccNo4
---------  ----------- -------------- --------- ------------ ------------- ------------- -------------
 1         Jack        123 Blahst       1        12345        345345        443453              
 2         John        234 BlahAVE      2        99999
 3         Sam         2123 Blahway     3        88888        7777777

1 个答案:

答案 0 :(得分:1)

以下是一些方法 - 一个使用11g及以上的PIVOT关键字,另一个使用MAX()和group by的旧式数据透视。

方法1:

with tablea as (select 1 id, 'Jack' name, '123 blahST' address from dual union all
                select 2 id, 'John' name, '234 blahAVE' address from dual union all
                select 3 id, 'Sam' name, '2123 blahWay' address from dual),
     tableb as (select 1 id, 12345 accno from dual union all
                select 1 id, 345345 accno from dual union all
                select 1 id, 443453 accno from dual union all
                select 2 id, 99999 accno from dual union all
                select 3 id, 88888 accno from dual union all
                select 3 id, 77777 accno from dual),
      b_res as (select *
                from   (select id,
                               accno,
                               row_number() over (partition by id order by accno) rn
                        from   tableb)
                pivot  (max(accno)
                        for rn in (1 as accno1,
                                   2 as accno2,
                                   3 as accno3,
                                   4 as accno4,
                                   5 as accno5)))
select ta.id ta_id,
       ta.name ta_name,
       ta.address ta_address,
       tb.id tb_id,
       tb.accno1 tb_accno1,
       tb.accno2 tb_accno2,
       tb.accno3 tb_accno3,
       tb.accno4 tb_accno4,
       tb.accno5 tb_accno5
from   tablea ta
       inner join b_res tb on ta.id = tb.id;

     TA_ID TA_NAME TA_ADDRESS        TB_ID  TB_ACCNO1  TB_ACCNO2  TB_ACCNO3  TB_ACCNO4  TB_ACCNO5
---------- ------- ------------ ---------- ---------- ---------- ---------- ---------- ----------
         1 Jack    123 blahST            1      12345     345345     443453                      
         2 John    234 blahAVE           2      99999                                            
         3 Sam     2123 blahWay          3      77777      88888              

方法2:

with tablea as (select 1 id, 'Jack' name, '123 blahST' address from dual union all
                select 2 id, 'John' name, '234 blahAVE' address from dual union all
                select 3 id, 'Sam' name, '2123 blahWay' address from dual),
     tableb as (select 1 id, 12345 accno from dual union all
                select 1 id, 345345 accno from dual union all
                select 1 id, 443453 accno from dual union all
                select 2 id, 99999 accno from dual union all
                select 3 id, 88888 accno from dual union all
                select 3 id, 77777 accno from dual),
      b_res as (select id,
                       max(case when rn = 1 then accno end) accno1,
                       max(case when rn = 2 then accno end) accno2,
                       max(case when rn = 3 then accno end) accno3,
                       max(case when rn = 4 then accno end) accno4,
                       max(case when rn = 5 then accno end) accno5
                from   (select id,
                               accno,
                               row_number() over (partition by id order by accno) rn
                        from   tableb)
                group by id)
select ta.id ta_id,
       ta.name ta_name,
       ta.address ta_address,
       tb.id tb_id,
       tb.accno1 tb_accno1,
       tb.accno2 tb_accno2,
       tb.accno3 tb_accno3,
       tb.accno4 tb_accno4,
       tb.accno5 tb_accno5
from   tablea ta
       inner join b_res tb on ta.id = tb.id;

     TA_ID TA_NAME TA_ADDRESS        TB_ID  TB_ACCNO1  TB_ACCNO2  TB_ACCNO3  TB_ACCNO4  TB_ACCNO5
---------- ------- ------------ ---------- ---------- ---------- ---------- ---------- ----------
         1 Jack    123 blahST            1      12345     345345     443453                      
         2 John    234 blahAVE           2      99999                                            
         3 Sam     2123 blahWay          3      77777      88888