Доступ к дочерним узлам в столбцах SQLXML с помощью XQuery

У меня есть база данных, в которой есть таблица со столбцом XML. XML-данные имеют набор дочерних узлов, которые выглядят примерно так:

<test>
  <result id="1234">
    <data elementname="Message">some error message</data>
    <data elementname="Cat">Cat01</data>
    <data elementname="Type">WARNING</data>
  </result>
  <result id="5678">
    <data elementname="Message">some error message</data>
    <data elementname="Cat">Cat01</data>
    <data elementname="Type">WARNING</data>
  </result>
</test>

Элемент Cat может иметь несколько различных значений. Я пытаюсь создать отчеты по этим данным, поэтому я хотел бы получить список всех категорий по нашим данным. Это мой запрос:

Select Id, XmlData.query('/test/result/data[@elementname = ''Cat''] ')  AS  Message
From Table
WHERE XmlData.exist('/test/result/data[@elementname = ''Cat'']') = 1
ORDER BY FriendlyName

Это правильно получает все строки в моей таблице с этим типом категоризации (в той же таблице будут другие результаты без этого элемента), но все категории объединены в один столбец для каждой записи таблицы:

Id1, <data elementname="Cat">Cat01</data><data elementname="Cat">Cat01</data>
Id2, <data elementname="Cat">Cat01</data><data elementname="Cat">Cat01</data>

Я включаю столбец Id, чтобы было легко увидеть, откуда поступают данные, основная проблема в том, что я могу заставить его объединять значения только для каждой строки - мне нужно, чтобы каждый из этих элементов данных имел свою собственную строку, тогда, возможно, сделайте Select Distinct для результата.

Есть ли способ сделать это?

Спасибо


person JohnL    schedule 23.05.2011    source источник


Ответы (1)


Всегда Google после публикации вопроса....

Думаю, я нашел ответ здесь: http://blogs.msdn.com/b/simonince/archive/2009/04/24/flattening-xml-data-in-sql-server.aspx

SELECT  DISTINCT  cref.value('(text())[1]', 'varchar(50)') as Cat
FROM   
      SGIS CROSS APPLY 
      Data.nodes('/test/result') AS Results(rref) CROSS APPLY
      rref.nodes('data[@elementname = ''Cat'']') AS Categories(cref)  

Кажется, ключом являются ключевые слова Cross Apply

person JohnL    schedule 24.05.2011