Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

T-SQL and XML - concatenate parent and multiple child elements into result set

Here is the XML:

<?xml version="1.0" encoding="UTF-16"?>
<Response>
  <Offers>
    <Car>
      <Group>ECMR</Group>
    </Car>
    <Insurances>
      <Optional>
        <Code>BE</Code>
      </Optional>
      <Optional>
        <Code>BF</Code>
      </Optional>
      <Optional>
        <Code>I</Code>
      </Optional>
      <Optional>
        <Code>LD</Code>
      </Optional>
    </Insurances>
  </Offers>
  <Offers>
    <Car>
      <Group>CDMR</Group>
    </Car>
    <Insurances>
      <Optional>
        <Code>BA</Code>
      </Optional>
      <Optional>
        <Code>BG</Code>
      </Optional>
      <Optional>
        <Code>IS</Code>
      </Optional>
      <Optional>
        <Code>LS</Code>
      </Optional>
    </Insurances>
  </Offers>
</Response>

Using this XML and within a single SELECT statement in a SQL Server stored procedure, I would like to create a result set that looks like this:

Group           Codes
--------------------------
ECMR            BE,BF,I,LD
CDMR            BG,BA,IS,LS

Each record in the result set contains a column for the <Car><Group>group</Group></Car> and another column for the concatenation of each <Insurances><Optional><Code>code</Code></Optional></Insurances>.

Is this possible?

like image 271
rstuppi Avatar asked Nov 15 '12 01:11

rstuppi


2 Answers

select T.N.value('(Car/Group/text())[1]', 'varchar(10)') as [Group],
       (
         select ','+T2.N.value('(./text())[1]', 'varchar(10)')
         from T.N.nodes('Insurances/Optional/Code') as T2(N)
         for xml path(''),  type
       ).value('substring(./text()[1], 2)', 'varchar(100)') as Codes
from @XML.nodes('/Response/Offers') as T(N)
like image 130
Mikael Eriksson Avatar answered Oct 17 '22 03:10

Mikael Eriksson


Try this

DECLARE @x XML
SELECT @x = N'<?xml version="1.0" encoding="UTF-16"?>
<Response>
  <Offers>
    <Car>
      <Group>ECMR</Group>
    </Car>
    <Insurances>
      <Optional>
        <Code>BE</Code>
      </Optional>
      <Optional>
        <Code>BF</Code>
      </Optional>
      <Optional>
        <Code>I</Code>
      </Optional>
      <Optional>
        <Code>LD</Code>
      </Optional>
    </Insurances>
  </Offers>
  <Offers>
    <Car>
      <Group>CDMR</Group>
    </Car>
    <Insurances>
      <Optional>
        <Code>BA</Code>
      </Optional>
      <Optional>
        <Code>BG</Code>
      </Optional>
      <Optional>
        <Code>IS</Code>
      </Optional>
      <Optional>
        <Code>LS</Code>
      </Optional>
    </Insurances>
  </Offers>
</Response>'

;With CTE AS(
SELECT
    X.value('Group[1]' ,'varchar(15)') As [Group],    
    Y.value('Code[1]' ,'varchar(15)') AS [Codes]
FROM 
@x.nodes('//Response/Offers/Car') T(X)
CROSS APPLY X.nodes('../Insurances/Optional') U(Y))

Select 
    [Group]
    , [Codes] = Stuff((Select ',' + CAST([Codes] AS vARCHAR(MAX))
      FROM CTE c2
      WHERE c2.[Group] = c1.[Group]
      FOR XML PATH('')
      ),1,1,'')
From CTE c1
Group By c1.[Group]

Result

Group   Codes
ECMR    BE,BF,I,LD
CDMR    BA,BG,IS,LS
like image 45
Niladri Biswas Avatar answered Oct 17 '22 03:10

Niladri Biswas