I have the following XML:
<xmlRoot>
<DomainName>sample.com</DomainName>
<UserCountsByTemplate>
<KeyValueOfstringint>
<Key>default</d2p1:Key>
<Value>20</d2p1:Value>
</KeyValueOfstringint>
<KeyValueOfstringint>
<Key>basic</d2p1:Key>
<Value>66</d2p1:Value>
</KeyValueOfstringint>
</UserCountsByTemplate>
</xmlRoot>
I am trying to get two rows to be returned like so:
Domain TemplateName TemplateCount
---------- ------------ -------------
sample.com default 20
sample.com basic 66
I have tried the following:
DECLARE @info XML
SELECT @info = '<xmlRoot><DomainName>sample.com</DomainName><UserCountsByTemplate><KeyValueOfstringint><Key>default</Key><Value>20</Value></KeyValueOfstringint><KeyValueOfstringint><Key>basic</Key><Value>66</Value></KeyValueOfstringint></UserCountsByTemplate></xmlRoot>'
SELECT
row.value('DomainName[1]','NVARCHAR(255)') AS [DomainName]
, row2.value('.','NVARCHAR(255)') AS [TemplateName]
, row3.value('.','INT') AS [TemplateCount]
FROM @info.nodes('/xmlRoot[1]') T1(row)
CROSS APPLY @info.nodes('/xmlRoot/UserCountsByTemplate/KeyValueOfstringint/Key') T2(row2)
CROSS APPLY @info.nodes('/xmlRoot/UserCountsByTemplate/KeyValueOfstringint/Value') T3(row3)
But get the following results:
Domain TemplateName TemplateCount
---------- ------------ -------------
sample.com default 20
sample.com basic 20
sample.com default 66
sample.com basic 66
Any ideas as to where I am going wrong with this?
You’re not correlating your access to Key and your access to value – so you’re effectively producing a cross join between all keys and all values.
Instead, I’m extracting the
KeyValueOfstringIntnodes, and then accessing different elements in thevalue()calls. But bothvalue()calls are operating on the same node (for each row).