1

I have XML data in table "sample" column name "xmlrec" that looks like:

<row id='1'>
 <c1>rec1</c1>
 <c2>a</c2>
 <c2>b</c2>
 <c2>c</c2>
</row>

The same needs to be transformed as below:

c1      c2
----    ----
rec1    a
rec1    b
rec1    c

Please help

Salman A
  • 262,204
  • 82
  • 430
  • 521
Praveen
  • 29
  • 2

2 Answers2

3

You can use CROSS APPLY xmlrec.nodes('/row/c2') to find all c2 nodes. Finding the corresponding c1 is easy:

SELECT n.value('(../c1)[1]', 'VARCHAR(100)') AS c1
     , n.value('.', 'VARCHAR(100)') AS c2
FROM sample
CROSS APPLY xmlrec.nodes('/row/c2') AS x(n)
Salman A
  • 262,204
  • 82
  • 430
  • 521
  • 1
    Exactly what i was about to post. +1 from me. – Thom A May 02 '19 at 13:16
  • Not exactly the same but this query suffers from the same issues as in [this question](https://stackoverflow.com/a/24199428/569436). – Mikael Eriksson May 02 '19 at 14:37
  • Thanks all for the solution. It worked.. I have adopted below solution SELECT n.value('(../c1)[1]', 'VARCHAR(100)') AS c1 , n.value('.', 'VARCHAR(100)') AS c2 FROM sample CROSS APPLY xmlrec.nodes('/row/c2') AS x(n) – Praveen May 03 '19 at 14:13
3

I'd prefer forward-navigation. It is possible to use ../c1 as in the other answer, but - as far as I know - performance is not the best. This is an alternative:

DECLARE @xml XML =
N'<row id="1">
 <c1>rec1</c1>
 <c2>a</c2>
 <c2>b</c2>
 <c2>c</c2>
</row>';

SELECT A.r.value('@id','int') AS row_id
      ,A.r.value('(c1/text())[1]','nvarchar(10)') AS c1
      ,B.c2.value('text()[1]','nvarchar(10)') AS c2
FROM @xml.nodes('/row') A(r)
CROSS APPLY A.r.nodes('c2') B(c2);

If there is only one <row> within your XML, this was best

SELECT @xml.value('(/row/@id)[1]','int') AS row_id
      ,@xml.value('(/row/c1/text())[1]','nvarchar(10)') AS c1
      ,B.c2.value('text()[1]','nvarchar(10)') AS c2
FROM @xml.nodes('/row/c2') B(c2);
Shnugo
  • 66,100
  • 9
  • 53
  • 114
  • + 1 "performance is not the best" I wrote something about it [here](https://stackoverflow.com/a/24199428/569436) – Mikael Eriksson May 02 '19 at 14:39
  • 1
    @MikaelEriksson I did read your brilliant answer a while ago and had this in mind, when I posted this hint :-) But I did not remember the link, thanks for passing by! – Shnugo May 02 '19 at 14:56