【问题标题】:How to merge 2 tables into 1 row, with multiple entries from second table in Oracle SQL如何将 2 个表合并为 1 行,Oracle SQL 中的第二个表中有多个条目
【发布时间】:2020-09-30 13:47:32
【问题描述】:

关于 (Oracle) SQL 的新蜜蜂问题。 我想要这张桌子:

ash_id  ash_contact_name ash_contact_telefoonnummber
15313   Name1   022457852114
15313   Name2   122457852114
15313   Name3   222457852114
15313   Name4   322457852114
15313   Name5   422457852114

在 1 行中看起来像这样:


15313 Name1 022457852114 Name2  122457852114    Name3   222457852114 Name4  322457852114 Name5  422457852114

所以我从第一个表中只得到 1 倍的 id 和多个名称的 coloms 我的代码现在看起来像这样:

select ash.ash_id ,
       con.ash_contact_name, con.ash_contact_telefoonnummer
from D00ASH01.ash_admin_stakeholder ash,ash_contacts con
where con.ash_id = ash.ash_id  and con.ash_id = 15313
order by ash.ash_id 

最终代码虽然不包括“con.ash_id = 15313”,但我需要拥有所有条目。最终结果将包括第一个表中的更多字段,所以我不能只使用第二个表。现在,我想开始简单地构建它。 我试图让它与一个连接一起工作,但没有成功。 欢迎所有建议, 谢谢

【问题讨论】:

  • 您可以通过使用其唯一的 Id 使用内连接来合并两个表,通过创建主键和外键您可以合并两个表并连续获取数据。

标签: sql join merge


【解决方案1】:

检查一下,它可能会对您有所帮助。如果不是,请告诉我。

SELECT ash.ash_id , con.ash_contact_name, con.ash_contact_telefoonnummer FROM D00ASH01.ash_admin_stakeholder as ash INNER JOIN ash_contacts as con ON con.ash_id = ash.ash_id WHERE con.ash_id = 15313 ORDER BY ash.ash_id;

【讨论】:

  • 嗨,这仍然给了我多行。我需要的是关于 1 row 中相同 con.ash_id 的所有字段。所以还没解决。
【解决方案2】:

SELECT * FROM ash INNER JOIN con USING(ash_id) where con_id = 15313 ORDER BY ash_id ;

【讨论】:

  • 对不起,不起作用,结果超过 1 行,我需要的是表 2 中与 1 行中的 id=15313 相关的多行中的所有字段。为了测试它,我需要像这样重写你的答案:SELECT * FROM D00ASH01.ash_admin_stakeholder ash INNER JOIN ash_contacts con USING(ash_id) Where ash_id = 15313 ORDER BY ash_id ;
【解决方案3】:

我确实得到了解决方案:

select 
    c.ash_id, 
    c.ash_naam_kbo_NL ,
    c.ash_naam_kbo_FR ,
    c.ash_naam_kbo_DE,
    max(Case when rn = 1 then c.ASH_CONTACT_NAME else null end) as name1,
    max(Case when rn = 1 then c.ASH_CONTACT_GSMNUMMER else null end) as gsm1,
    max(Case when rn = 1 then c.ASH_CONTACT_FAXNUMMER else null end) as fax1, 
    max(Case when rn = 1 then c.ASH_CONTACT_EMAILADRES else null end) as email1, 
    max(Case when rn = 2 then c.ASH_CONTACT_NAME else null end) as name2,
    max(Case when rn = 2 then c.ASH_CONTACT_GSMNUMMER else null end) as gsm2,
    max(Case when rn = 2 then c.ASH_CONTACT_FAXNUMMER else null end) as fax2, 
    max(Case when rn = 2 then c.ASH_CONTACT_EMAILADRES else null end) as email2
from (
    select 
        table_ash.ash_id, 
        table_ash.ash_naam_kbo_NL ,
        table_ash.ash_naam_kbo_FR ,
        table_ash.ash_naam_kbo_DE,
        table_contacts.ASH_CONTACT_NAME,
        table_contacts.ASH_CONTACT_GSMNUMMER,
        table_contacts.ASH_CONTACT_FAXNUMMER,
        table_contacts.ASH_CONTACT_EMAILADRES,
        ROW_NUMBER () over (partition by table_ash.ash_id order by table_ash.ash_id, 
        table_ash.ash_naam_kbo_NL) rn
    from 
        ASH_ADMIN_STAKEHOLDER table_ash, 
        ash_contacts table_contacts
    where 
        table_ash.ash_id = table_contacts.ash_id) c
    group by  
        c.ash_id, 
        c.ash_naam_kbo_NL ,
        c.ash_naam_kbo_FR ,
        c.ash_naam_kbo_DE;

所以,“选择”中有一个“选择”。诀窍是生成一个 rownnumber 并像索引一样使用它。对于尽可能多的行号,在查询中包含一个 max 函数。这段代码是我需要的答案的基础。

【讨论】:

    【解决方案4】:

    用 Oracle 编写的 SQL 代码:

    WITH CTE AS(
    SELECT
                UP.CLASS,
                UP.NS || UP.RN AS NSR,
                UP.VAL
    FROM
                (
                SELECT
                            ROW_NUMBER ()
             OVER (
               PARTITION BY S.CLASS
                ORDER BY
                            S.CLASS) RN,
                            S.*
                FROM
                            STAKEHOLDER S
                ORDER BY
                            CLASS,
                            SID) SS
    UNPIVOT (VAL FOR NS IN (NAME, SID)) UP
    )
    SELECT
                *
    FROM
                CTE
    PIVOT(MAX(VAL) FOR NSR IN ('NAME1' AS NAME1,
                'SID1' AS SID1,
                'NAME2' AS NAME2,
                'SID2' AS SID2,
                'NAME3' AS NAME3,
                'SID3' AS SID3))
    

    如果我们以自然的思维方式处理它,这并不难。按 CLASS 对表进行分组后,我们将 NAME 和 SID 列转换为行,并创建名称命令值以转换为列。名称的格式为原始列名+子组数,如组 1 为 NAME1、SID1、NAME2、SID2,…,组 2 为 NAME1、SID1、…。然后我们连接组并将行转置为列。问题是 SQL 不支持动态行到列/列到行的转置。当列数较少且列数固定时,该语言可以进行换位。随着列数的增加,场景变得越来越尴尬。枚举所有要转换的列很复杂,SQL 代码变得臃肿。如果列是动态的,SQL 需要转向复杂而迂回的方式来处理它们。

    然而,使用开源集算器 SPL 编写转置任务真的很容易:

    | |A|
    |1|=connect("ORACLE")|
    |2|=A1.query@x("SELECT \* FROM STAKEHOLDER ORDER BY CLASS,SID")|
    |3|=A2.fname().m(2:)|
    |4|=A2.group@o(CLASS)|
    |5|=A4.conj(\~.news(A3;CLASS,A3(#)/A4.\~.#:COL,\~:VAL))|
    

    【讨论】:

      猜你喜欢
      • 2022-01-02
      • 1970-01-01
      • 1970-01-01
      • 2016-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-07
      • 1970-01-01
      相关资源
      最近更新 更多