Skip to main content
Announcements
Qlik Connect 2024! Seize endless possibilities! LEARN MORE

Querying XML data from a database and returning multiple rows for an element

cancel
Showing results for 
Search instead for 
Did you mean: 
dgreenberg
Luminary Alumni
Luminary Alumni

Querying XML data from a database and returning multiple rows for an element

Last Update:

Sep 21, 2022 1:07:35 PM

Updated By:

Sue_Macaluso

Created date:

Oct 10, 2019 8:07:55 AM

Running a query against an XML table in a database can present certain challenges.

One of the more difficult ones was figuring out how to get multiple values out of a record in an XML table.

 

XMLdata:
<root1>
     <R>
           <period>2019-Q1</period>
           <period>2019-Q2</period>
           <period>2018-Q1</period>
           <period>2018-Q2</period>
           <Tgroup>117</Tgroup>
           <Tgroup>231</Tgroup>
           <ToData>12</ToData>
           <ToData>241</ToData>
           <ToData>216</ToData>
     </R>
</root1>

 

As you can see the 3 fields (period,Tgroup,ToData) all have multiple values for this record.

Normally we would write a SQL query like this one:

select
INumber,
N.C.value('(R/period)[1]','nvarchar(max)') as period, N.C.value('(R/TGroup)[1]','nvarchar(max)') as Tgroup,
N.C.value('(R/ToData)[1]','nvarchar(max)') as ToData,
from DataTable cross apply [XMLdata].nodes('/root') as N(C);

The problem with the above query is only 1 value will be returned for those 3 fields no matter how many exist in the XML for that record.

To solve this problem use a query like the one below.

select
EF.INumber,
XMLdata,
period,
TGroup,
ToData
FROM DataTable EF
Cross apply (
           SELECT distinct
                  INumber,
                  c.value('.[1]', 'varchar(200)') as period,
                  d.value('.[1]', 'varchar(200)') as TGroup,
                  e.value('.[1]', 'varchar(200)') as ToData
           FROM DataTable A
      outer apply XMLdata.nodes('/root1/R/period') as T(C)
      outer apply XMLdata.nodes('/root1/R/TGroup') as U(D)
     outer apply XMLdata.nodes('/root1/R/ToData') as V(e)
     where EF.INumber=A.INumber
)A

 

Tags (1)
Version history
Last update:
‎2022-09-21 01:07 PM
Updated by: