2017-09-28 2 views
2

Est-il possible d'interroger OUTER APPLY nodes(ChildTag1 OR ChildTag2) comme ma requête en cours, en utilisant nodes(ChildTag1) OUTER APPLY nodes(ChildTag2) produit une sortie croisée rejoint incorrecte:Dans T SQL, comment puis-je interroger et dé-pivoter le contenu d'un tag XML?

Requête en cours:

;WITH CTE AS 
(SELECT 'Sample Text 1' AS ID, 
       CONVERT(XML, '<Root> 
           <ParentTag ParentTagID="Sample Text 2"> 
           <ChildTag1>5</ChildTag1> 
           <ChildTag1>6</ChildTag1> 
           <ChildTag2>7</ChildTag2> 
           <ChildTag2>8</ChildTag2> 
           </ParentTag> 
          </Root>' 
        ) AS SampleXML 
) 
SELECT ID, 
     Root.ParentTag.value('@ParentTagID','NVARCHAR(MAX)') AS ParentTagID, 
     RootParentTag1.ChildTag1.value('(text())[1]', 'NVARCHAR(MAX)') AS ChildTag1, 
     RootParentTag2.ChildTag2.value('(text())[1]', 'NVARCHAR(MAX)') AS ChildTag2 
FROM CTE 
OUTER APPLY CTE.SampleXML.nodes('/Root/ParentTag') as Root(ParentTag) 
OUTER APPLY Root.ParentTag.nodes('ChildTag1') as RootParentTag1(ChildTag1) 
OUTER APPLY Root.ParentTag.nodes('ChildTag2') as RootParentTag2(ChildTag2) 

Courant de sortie:

ChildTag1 ChildTag2 
5   7 
5   8 
6   7 
6   8 

Cette requête retravaillé L'utilisation de l'union et de deux sections distinctes d'interrogation XML produit la sortie correcte, mais est-ce la méthode la plus efficace ou existe-t-il un moyen plus facile et plus propre?

Reworked Requête:

;WITH CTE AS 
(SELECT 'Sample Text 1' AS ID, 
       CONVERT(XML, '<Root> 
           <ParentTag ParentTagID="Sample Text 2"> 
           <ChildTag1>5</ChildTag1> 
           <ChildTag1>6</ChildTag1> 
           <ChildTag1>7</ChildTag1> 
           <ChildTag2>8</ChildTag2> 
           <ChildTag2>9</ChildTag2> 
           <ChildTag2>10</ChildTag2> 
           </ParentTag> 
          </Root>' 
        ) AS SampleXML 
) 
SELECT ID, 
     Root.ParentTag.value('@ParentTagID','NVARCHAR(MAX)') AS ParentTagID, 
     RootParentTag1.ChildTag1.value('(text())[1]', 'NVARCHAR(MAX)') AS ChildTag1, 
     NULL 
FROM CTE 
OUTER APPLY CTE.SampleXML.nodes('/Root/ParentTag') as Root(ParentTag) 
OUTER APPLY Root.ParentTag.nodes('ChildTag1') as RootParentTag1(ChildTag1) 
UNION 
SELECT ID, 
     Root.ParentTag.value('@ParentTagID','NVARCHAR(MAX)') AS ParentTagID, 
     NULL, 
     RootParentTag2.ChildTag2.value('(text())[1]', 'NVARCHAR(MAX)') AS ChildTag2 
FROM CTE 
OUTER APPLY CTE.SampleXML.nodes('/Root/ParentTag') as Root(ParentTag) 
OUTER APPLY Root.ParentTag.nodes('ChildTag2') as RootParentTag2(ChildTag2) 

Reworked Sortie:

ChildTag1 ChildTag2 
5   NULL 
6   NULL 
NULL   7 
NULL   8 
+0

Veuillez inclure la requête que vous avez maintenant dans la question. –

+0

Bonjour @TT. J'ai ajouté la requête en cours –

Répondre

1

Celui-ci est un peu plus court, en se fondant toujours sur ALL UNION (car pas de doublons sont possibles dans votre XML par exemple). Je ne vois pas de problèmes en termes de performances ici.

;WITH CTE AS 
(SELECT 'Sample Text 1' AS ID, 
       CONVERT(XML, '<Root> 
           <ParentTag ParentTagID="Sample Text 2"> 
           <ChildTag1>5</ChildTag1> 
           <ChildTag1>6</ChildTag1> 
           <ChildTag1>7</ChildTag1> 
           <ChildTag2>8</ChildTag2> 
           <ChildTag2>9</ChildTag2> 
           <ChildTag2>10</ChildTag2> 
           </ParentTag> 
          </Root>' 
        ) AS SampleXML 
) 
SELECT 
    n.v.value('.','INT') AS ChildTag1, 
    NULL AS ChildTag2 
FROM 
    CTE 
    CROSS APPLY SampleXML.nodes('/Root/ParentTag/ChildTag1/text()') as n(v) 
UNION ALL 
SELECT 
    NULL AS ChildTag1, 
    n.v.value('.','INT') AS ChildTag2 
FROM 
    CTE 
    CROSS APPLY SampleXML.nodes('/Root/ParentTag/ChildTag2/text()') as n(v)