Родительский и дочерний XQuery

Пример:

DECLARE @XML XML = '
<Items>
    <document id="doc1" value="100">
        <details>
            <detail detailID="1" detailValue="20"/>
            <detail detailID="2" detailValue="80"/>
        </details>
    </document>
    <document id="doc2" value="0">
        <details>
        </details>
    </document>
</Items>
'

Мне нужны такие результаты:

id    value    detailID   detailValue
doc1  100      1          20
doc1  100      2          80
doc2  0        NULL       NULL

Пытался:

SELECT document.value('../../@docID', 'VARCHAR(10)') AS 'docID',
       document.value('../../@value', 'INT') AS 'value',
       document.value('@detailID', 'VARCHAR(10)') AS 'detailID',
       document.value('@detailValue', 'INT') AS 'detailValue'
FROM   @XML.nodes('Items/document/details/detail') AS Documents(document)

Но doc2 не указан... Кроме того, пробовал использовать CROSS JOIN и INNER JOIN, но производительность очень плохая.


person Ragys    schedule 28.03.2013    source источник


Ответы (2)


Попробуй это:

SELECT document.value('@id', 'VARCHAR(10)') AS docID,
       document.value('@value', 'INT') AS value,
       Detail.value('@detailID', 'INT') as DetailId,
       Detail.value('@detailValue', 'INT') as DetailValue
FROM   @XML.nodes('Items/document') AS Documents(document)
       outer apply Documents.document.nodes('details/detail') as Details(Detail);
person Kevin Suchlicki    schedule 28.03.2013
comment
Пожалуйста. Но производительность ужасна? Вы, должно быть, делаете это с некоторыми очень большими XML-документами (или с большим количеством записей). Удачи! - person Kevin Suchlicki; 28.03.2013
comment
Не совсем (приложение 3 docs.) ... Проблема глубокая ... с вашим методом мне пришлось бы сделать 3 внешних приложения ... 3 docs = ответ через 6 секунд ... - person Ragys; 28.03.2013

Всего одна добавленная деталь:

@XML.nodes('//whatever_depth') AS Documents(document)

Использование '//' Позволяет запрашивать не напрямую от root

С уважением, Деннес

person user3755645    schedule 19.06.2014