【问题标题】:SQL query XML multiple nodes a columnsSQL查询XML多节点一列
【发布时间】:2018-10-18 14:24:24
【问题描述】:

我在 DB 列中有 XML 和其他一些列:

RowID    PeopleXML
1        <people>2 people nodes</people>
2        <people>3 people nodes</people>

每个 XML 列的结构类似于

<people>
    <person Name="Aaron" Lastname="Man"></person>   
    <person Name="Barbara" Lastname="Woman"></person>
</people>

人中没有固定数量的人节点。它们可能没有或任何给定的数量。

我想使用 SQL Server 进行查询。我需要每个数据行的所有人都在一行中。例如

RowID  name1  lastname1  name2    lastname2
1      Aaron  Man        Barbara  Woman
2      .....  ....       ....     .....     ...  ...

谢谢。

【问题讨论】:

    标签: xml sql-server-2008 tsql pivot


    【解决方案1】:

    你可以这样试试:

    DECLARE @tbl TABLE(RowID INT IDENTITY,PeopleXML XML);
    INSERT INTO @tbl VALUES
     (N'<people type="many people">
            <person Name="Aaron" Lastname="Man"></person>   
            <person Name="Barbara" Lastname="Woman"></person>
        </people>')
    ,(N'<people type="one person">
            <person Name="Lonely" Lastname="Boy"></person>   
        </people>')
    ,(N'<people type="nobdy">
        </people>')
    ,(NULL);
    
    SELECT RowID
          ,PeopleXML.value(N'(/people/@type)[1]',N'nvarchar(max)') AS TypeDescription 
          ,pers.value(N'@Name',N'nvarchar(max)') AS PersonName
          ,pers.value(N'@Lastname',N'nvarchar(max)') AS PersonLastname
    FROM @tbl
    OUTER APPLY PeopleXML.nodes(N'/people/person') AS A(pers);
    

    结果

    RowID   TypeDescription PersonName  PersonLastname
    1       many people     Aaron       Man
    1       many people     Barbara     Woman
    2       one person      Lonely      Boy
    3       nobdy           NULL        NULL
    4       NULL            NULL        NULL
    

    如果您想将结果减少到带有&lt;Person&gt; 的行,请使用CROSS APPLY。

    更新:透视

    我刚刚看到,您需要一行中的结果...在大多数情况下不是您能做的最好的...应该仅用于输出...

    WITH Numbered AS
    (
        SELECT RowID
              ,ROW_NUMBER() OVER(PARTITION BY RowID ORDER BY (SELECT NULL)) AS PersonIndex
              ,PeopleXML.value(N'(/people/@type)[1]',N'nvarchar(max)') AS TypeDescription 
              ,pers.value(N'@Name',N'nvarchar(max)') AS PersonName
              ,pers.value(N'@Lastname',N'nvarchar(max)') AS PersonLastname
        FROM @tbl
        OUTER APPLY PeopleXML.nodes(N'/people/person') AS A(pers)
    )
    SELECT RowID
          ,MAX(CASE WHEN PersonIndex=1 THEN PersonName END) AS Nm1
          ,MAX(CASE WHEN PersonIndex=1 THEN PersonLastname END) AS LNm1
          --second person
          ,MAX(CASE WHEN PersonIndex=2 THEN PersonName END) AS Nm2
          ,MAX(CASE WHEN PersonIndex=2 THEN PersonLastname END) AS LNm2
          --add as many as you need
    FROM Numbered 
    GROUP BY RowID;
    

    结果

        Nm1    LNm1     Nm2     LNm2
    1   Aaron   Man     Barbara Woman
    2   Lonely  Boy     NULL    NULL
    3   NULL    NULL    NULL    NULL
    4   NULL    NULL    NULL    NULL
    

    【讨论】:

    • 非常感谢。我会试试这个并发布结果。
    猜你喜欢
    • 2022-11-15
    • 1970-01-01
    • 2022-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-15
    • 2012-06-30
    • 1970-01-01
    相关资源
    最近更新 更多