【问题标题】:ORACLE Join table to select multiple record in 1 rowORACLE 连接表以选择 1 行中的多条记录
【发布时间】:2023-04-04 09:50:01
【问题描述】:

我有两张桌子

TableA:主表,每个名为 ID的字段有 1 条记录
TableB:可以包含名为 的字段的多条记录>身份证

我想根据 IDTableATableB 在 1 行中选择所有内容以获得最终结果

例子

样本记录 来自 TableA

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

来自表B

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

【问题讨论】:

  • 这是用于 MySQL 还是 Oracle 数据库?这是两个不同的 DBMS 平台 - 请酌情修改标签。另外,最多只能有 4 个帐号吗?
  • 对不起甲骨文。我已经修好了。我会说 Max 在极少数情况下是 5,大多数时候它是 2 左右。

标签: database oracle join


【解决方案1】:

这里有几种方法 - 一种使用 11g 及更高版本中可用的 PIVOT 关键字,另一种使用使用 MAX() 和 group by 的旧式数据透视。

方法一:

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              

方法二:

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    

【讨论】:

  • 完全天才的人,很容易理解你的解决方案。我以前从未使用过pivot 函数。我真的要感谢你的帮助。
  • 嗨,一个问题,在第一种方法中,在临时表b_res 下,如果我在该查询中有一个连接,它会抛出枢轴最大值错误。你能帮忙ORA-00904: tableb.accno: invalid identifier我的查询更改为pivot (max(tableb.accno)
  • 您应该将此作为一个新问题提出,并发布所有相关信息,包括示例输入和预期输出数据。
  • 要再次解释这一点将非常困难。 :(
  • 真的吗?您知道有三个表,以及需要修改的现有语句。复制粘贴数据真的那么难吗?甚至是这个问题的链接?试图通过 cmets 解决您的新要求是不可能的。
猜你喜欢
  • 1970-01-01
  • 2022-01-24
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 2013-04-15
  • 1970-01-01
相关资源
最近更新 更多