Как сделать выбор из таблицы и из относительного столбца xml, разбивая на строки столбец XML? - PullRequest
0 голосов
/ 30 января 2020

У меня есть таблица T с двумя столбцами. Столбец A является столбцом varchar, а столбец B является столбцом XML.

Где-то внутри столбца B всегда есть следующий родительский тег: <Documents> ... </Documents>. Внутри много <Document>...</Document> потомков.

Я хотел бы получить набор результатов с двумя столбцами:

  • Столбец 1 должен содержать те же значения, что и столбец A;
  • В столбце 2 должно содержаться только одно <Document>...</Document>.

Например, Стартовая таблица T:

Column A | Column B
--------------------------------------------------------------------------
abc      | <Documents><Document>Doc 1</Document><Document>Doc 2</Document></Documents>

Ожидаемый результат:

Column 1 | Column 2
-------------------------------------
abc      |<Document>Doc 1</Document>
abc      |<Document>Doc 2</Document>

Я могу получить столбец 2 следующим образом (как видно из документов ):

SELECT T2.C.query('.')
FROM T
CROSS APPLY T.[Column B].nodes('*/Documents/*') as T (C)

, но вместо этого это не работает:

SELECT T.[Column A], T2.C.query('.')
FROM T
CROSS APPLY T.[Column B].nodes('*/Documents/*') as T2 (C)

Как получить ожидаемый результат тогда?

1 Ответ

1 голос
/ 30 января 2020

Вот как это сделать.

SQL

-- DDL and sample data population, start
DECLARE @tbl TABLE (ID CHAR(3), xmldata XML);;
INSERT INTO @tbl (ID, xmldata)
VALUES
('abc', '<Documents><Document>Doc 1</Document><Document>Doc 2</Document></Documents>')
, ('xyz', '<Documents><Document>Doc 10</Document><Document>Doc 20</Document></Documents>');
-- DDL and sample data population, end

SELECT ID
    , c.query('.') AS [Column 2]
FROM @tbl AS tbl
    CROSS APPLY tbl.xmldata.nodes('//Documents/Document') AS t(c);

Вывод

+-----+-----------------------------+
| ID  |          Column 2           |
+-----+-----------------------------+
| abc | <Document>Doc 1</Document>  |
| abc | <Document>Doc 2</Document>  |
| xyz | <Document>Doc 10</Document> |
| xyz | <Document>Doc 20</Document> |
+-----+-----------------------------+
...