【问题标题】:SQL or PL/SQL to return the value of nodes with same name to one rowSQL 或 PL/SQL 将同名节点的值返回到一行
【发布时间】:2018-04-27 11:59:12
【问题描述】:

我想从下面的 XML 返回以下内容。

ID            Departments
-----------   ------------------------------   
EMP10Level1   98,850,876,896,901,908,936,987

我尝试了一些方法,例如解析 XML 和使用 Listagg,但我得到的每个 ID 的值都相同。

希望更开明的头脑可以为我解决这个问题。

也是一个名为 ID 的列,其中包含 EMP10Level1,它是来自下面 PromotionID 标记的值。

 <Promotion>
    <MajorVersion>1</MajorVersion>
    <MinorVersion>7</MinorVersion>
    <PromotionID>EMP10Level1</PromotionID>
    <MultibuyGroup>
        <UseLowestNetValue>0</UseLowestNetValue>
        <MMGroupID>850</MMGroupID>
        <MMGroupID>901</MMGroupID>
        <MMGroupID>908</MMGroupID>
        <MMGroupID>936</MMGroupID>
        <MMGroupID>896</MMGroupID>
        <MMGroupID>987</MMGroupID>
        <MMGroupID>876</MMGroupID>
        <MMGroupID>98</MMGroupID>
        <TriggerOnLostSales>0</TriggerOnLostSales>
    </MultibuyGroup>
</Promotion>

【问题讨论】:

    标签: sql xml plsql


    【解决方案1】:

    这是使用嵌套排序 XMLTABLEs 的一种方法:

    WITH sample_data AS (SELECT XMLTYPE('<Promotion>
        <MajorVersion>1</MajorVersion>
        <MinorVersion>7</MinorVersion>
        <PromotionID>EMP10Level1</PromotionID>
        <MultibuyGroup>
            <UseLowestNetValue>0</UseLowestNetValue>
            <MMGroupID>850</MMGroupID>
            <MMGroupID>901</MMGroupID>
            <MMGroupID>908</MMGroupID>
            <MMGroupID>936</MMGroupID>
            <MMGroupID>896</MMGroupID>
            <MMGroupID>987</MMGroupID>
            <MMGroupID>876</MMGroupID>
            <MMGroupID>98</MMGroupID>
            <TriggerOnLostSales>0</TriggerOnLostSales>
        </MultibuyGroup>
    </Promotion>') xmldata FROM dual)
    SELECT ids.id,
           listagg(depts.department, ',') WITHIN GROUP (ORDER BY depts.department) departments
    FROM   sample_data sd
           CROSS JOIN XMLTABLE('/Promotion' PASSING sd.xmldata
                               COLUMNS ID VARCHAR2(20) PATH 'PromotionID',
                                       dept_xml XMLTYPE PATH 'MultibuyGroup') ids
           CROSS JOIN XMLTABLE('//MMGroupID' PASSING ids.dept_xml
                               COLUMNS department INTEGER PATH '.') depts
    GROUP BY ids.id;
    
    ID                   DEPARTMENTS
    -------------------- --------------------------------------------------------------------------------
    EMP10Level1          98,850,876,896,901,908,936,987
    

    【讨论】:

    • 优秀的解决方案,修改它以引用我的实际数据库列,并根据需要提取数据。非常感谢。
    【解决方案2】:

    不是很优雅,但这是另一个有效的方法:

    WITH TBL
         AS (SELECT xmltype (
                       '<Promotion>
                        <MajorVersion>1</MajorVersion>
                        <MinorVersion>7</MinorVersion>
                        <PromotionID>EMP10Level1</PromotionID>
                        <MultibuyGroup>
                            <UseLowestNetValue>0</UseLowestNetValue>
                            <MMGroupID>850</MMGroupID>
                            <MMGroupID>901</MMGroupID>
                            <MMGroupID>908</MMGroupID>
                            <MMGroupID>936</MMGroupID>
                            <MMGroupID>896</MMGroupID>
                            <MMGroupID>987</MMGroupID>
                            <MMGroupID>876</MMGroupID>
                            <MMGroupID>98</MMGroupID>
                            <TriggerOnLostSales>0</TriggerOnLostSales>
                        </MultibuyGroup>
                    </Promotion>')
                       Col1
               FROM DUAL)
    SELECT EXTRACTVALUE (col1, 'Promotion/PromotionID') AS ID,
           LTRIM (
              REPLACE (
                 REPLACE (EXTRACT (col1, 'Promotion/MultibuyGroup/MMGroupID'),
                          '<MMGroupID>',
                          ','),
                 '</MMGroupID>'),
              ',')
              AS DEPT
      FROM tbl
    

    【讨论】:

    • 我强烈推荐我的和这个答案的 OP 测试,看看哪一个更适合他们的情况。我发现 XMLTABLE 比 EXTRACT/EXTRACTVALUE 更快,但这可能只是在那个特定场景中(不是这个场景)。我很想看看结果,特别是如果这个答案更高效 *{:-)
    猜你喜欢
    • 2017-11-04
    • 1970-01-01
    • 2013-05-06
    • 1970-01-01
    • 2015-02-21
    • 1970-01-01
    • 2017-10-23
    • 2013-02-26
    • 1970-01-01
    相关资源
    最近更新 更多