SQL-запрос XML несколько узлов столбцов - PullRequest
0 голосов
/ 08 мая 2018

У меня есть 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      .....  ....       ....     .....     ...  ...

Спасибо.

1 Ответ

0 голосов
/ 08 мая 2018

Вы можете попробовать это так:

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

Используйте CROSS APPLY, если хотите уменьшить результат до строк с <Person>.

ОБНОВЛЕНИЕ: Pivoted

Я только что увидел, что вам нужен результат в одной строке ... В большинстве случаев это не самое лучшее, что вы можете сделать ... Должно быть только для вывода ...

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...