Sql server 按不同级别的名称选择某些重复的XML节点&;从所述节点中将子节点作为行重复

Sql server 按不同级别的名称选择某些重复的XML节点&;从所述节点中将子节点作为行重复,sql-server,xml,sql-server-openxml,Sql Server,Xml,Sql Server Openxml,以以下简化的XML为例: (摘自第三方行业批发商数据提供商提供的一个非常昂贵(而且很大)的XML产品提要,即我无法控制其模式/格式/内容) 我的任务是生成以下输出: 事实证明,这是极其困难的,原因有两个: 您会注意到3623949存在于组/组/组/组/(3级组)中,而3265725存在于组/组/(1级组)中-我需要选择所有节点,无论其嵌套级别如何(理想情况下是在父节点=时) 请注意中的节点-我需要选择重复的子节点(code\u Description&code\u Value)作为两个独立的列

以以下简化的XML为例:

(摘自第三方行业批发商数据提供商提供的一个非常昂贵(而且很大)的XML产品提要,即我无法控制其模式/格式/内容)

我的任务是生成以下输出:

事实证明,这是极其困难的,原因有两个:

  • 您会注意到
    3623949存在于
    组/组/组/组/
    (3级组)中,而
    3265725存在于
    组/组/
    (1级组)中-我需要选择所有
    节点,无论其嵌套级别如何(理想情况下是在父节点=
    时)

  • 请注意
    中的
    节点-我需要选择重复的子节点(code\u Description&code\u Value)作为两个独立的列,但还要注意
    中可能有任意数量的
    节点,我需要将它们全部选中(使[I]符号无效)

  • 我已经尽了最大努力使用TSQL
    OPENXML
    获取这些数据,但我能想到的唯一方法是为不同的组/组/级别复制代码,并且我还必须使用[0]符号硬编码一组其他_代码的出现次数,这是由于它们的变量性质;这是错误的

    SELECT  *
    FROM    OPENXML (@idoc, 'Company/Brand/Groups/Group/Product',2)
                            WITH (
                              PIP_code CHAR (20) 'Pip_code',
                              OtherCodeType CHAR (20) 'Other_Codes/Other_Code[1]/Code_Description',
                              OtherCodeValue CHAR (30) 'Other_Codes/Other_Code[1]/Code_Value',
                              OtherCodeType2 CHAR (20) 'Other_Codes/Other_Code[2]/Code_Description',
                              OtherCodeValue2 CHAR (30) 'Other_Codes/Other_Code[2]/Code_Value',
                              OtherCodeType3 CHAR (20) 'Other_Codes/Other_Code[3]/Code_Description',
                              OtherCodeValue3 CHAR (30) 'Other_Codes/Other_Code[3]/Code_Value'
                      )
    

    我们更愿意在TSQL中执行此操作(因为该XML文件已经在那里处理,用于其他与此处不相关的节点和路径),我们可以使用SQL Server 2008、2008 R2和SQL Server 2014,但是非SQL解决方案也会有帮助-我们在这一点上确实遇到了困难。

    因此,您真正想要做的是将选择语句设置为
    //其他\u代码
    -双正斜杠表示您需要每个
    其他\u代码
    节点,而不管其在层次结构中的位置,为每个
    其他\u代码节点提供一行。然后,您可以指定
    PipCode
    。/../Pip\u code
    ,当然,假设此部分的层次结构也不会一直更改(但这在语义上有何意义?)

    这:

    产生以下结果:

    PipCode                 Code_Description        Code_Value
    -----------------------------------------------------------------
    3623949                 EAN                     5013158781351                 
    3623949                 shipper EAN             503158781443                  
    3623949                 AMPP                    19192411000001107             
    3623949                 AMPP Manf               2061801000001104              
    3265725                 Outer EAN               5013158776531                 
    3265725                 AMPP                    11521811000001106             
    3265725                 AMPP Manf               2061801000001104              
    3265725                 EAN                     5013158776500                 
    

    先生,您是一个天才。或者您是一个比SQL更习惯XSLT的人;)很乐意帮忙
    DECLARE @doc xml = '<Company>
        <Code>7786</Code>
        <Brand>
            <!-- /../ -->
            <Groups>
                <Group>
                    <!-- /../ -->
                    <Group>
                        <!-- /../ -->
                        <Group>
                            <!-- /../ -->
                            <Product>
                                <Pip_code>3623949</Pip_code>
                                <!-- /../ -->
                                <Other_Codes>
                                    <Other_Code>
                                        <Code_Description>EAN</Code_Description>
                                        <Code_Value>5013158781351</Code_Value>
                                    </Other_Code>
                                    <Other_Code>
                                        <Code_Description>shipper EAN</Code_Description>
                                        <Code_Value>503158781443</Code_Value>
                                    </Other_Code>
                                    <Other_Code>
                                        <Code_Description>AMPP</Code_Description>
                                        <Code_Value>19192411000001107</Code_Value>
                                    </Other_Code>
                                    <Other_Code>
                                        <Code_Description>AMPP Manf</Code_Description>
                                        <Code_Value>2061801000001104</Code_Value>
                                    </Other_Code>
                                </Other_Codes>
                            </Product>
                        </Group>
                    </Group>
                </Group>
            </Groups>
        </Brand>
        <Brand>
            <!-- /../ -->
            <Groups>
                <Group>
                    <!-- /../ -->
                    <Product>
                        <Pip_code>3265725</Pip_code>
                        <!-- /../ -->
                        <Other_Codes>
                            <Other_Code>
                                <Code_Description>Outer EAN</Code_Description>
                                <Code_Value>5013158776531</Code_Value>
                            </Other_Code>
                            <Other_Code>
                                <Code_Description>AMPP</Code_Description>
                                <Code_Value>11521811000001106</Code_Value>
                            </Other_Code>
                            <Other_Code>
                                <Code_Description>AMPP Manf</Code_Description>
                                <Code_Value>2061801000001104</Code_Value>
                            </Other_Code>
                            <Other_Code>
                                <Code_Description>EAN</Code_Description>
                                <Code_Value>5013158776500</Code_Value>
                            </Other_Code>
                        </Other_Codes>
                    </Product>
                </Group>
            </Groups>
        </Brand>
    </Company>';
    
    DECLARE @idoc int;
    
    exec sp_xml_preparedocument @idoc OUTPUT, @doc;
    SELECT  *
    FROM    OPENXML(@idoc, '//Other_Code',1)
    WITH (
        PipCode CHAR (20) '../../Pip_code',
        Code_Description CHAR(20) 'Code_Description',
        Code_Value CHAR (30) 'Code_Value'
    )
    
    PipCode                 Code_Description        Code_Value
    -----------------------------------------------------------------
    3623949                 EAN                     5013158781351                 
    3623949                 shipper EAN             503158781443                  
    3623949                 AMPP                    19192411000001107             
    3623949                 AMPP Manf               2061801000001104              
    3265725                 Outer EAN               5013158776531                 
    3265725                 AMPP                    11521811000001106             
    3265725                 AMPP Manf               2061801000001104              
    3265725                 EAN                     5013158776500