Reputation: 11
I've the input data in SQL table in below format:
ID Text
1 <Key><Name>Adobe</Name><Display>Ado</Display></Key><Key>.....</Key>
2 <Key><Name></Name><Display>Microsoft</Display><Version>1.1</Version></Key>
There can be multiple keys for each ID.There could be several thousand rows in a table in above format. I've to generate the final sql output in below format
ID Name Display Version
1 Adobe Ado
1 xyz yz 1.2
2 Microsoft 1.1
I am using the below query to parse Text column, but getting all data in one row. How can I split that data in multiple rows as indicated above.
SELECT
CAST(CAST(Text AS XML).query('data(/Key/Name)') AS VARCHAR(MAX)) AS Name,
CAST(CAST(Text AS XML).query('data(/Key/Display)') as VARCHAR(MAX)) AS DisplayName,
CAST(CAST(Text AS XML).query('data(/Key/Version)') AS VARCHAR(MAX)) AS Version
FROM
ABC where ID = 1
Currently I am running this query for each ID at a time. Is there a way to run for all ID's together. Also, is there any other efficient way to get the desired output.
Upvotes: 1
Views: 617
Reputation: 7692
Here is the example:
-- Sample demonstrational schema
declare @t table (
Id int primary key,
TextData nvarchar(max) not null
);
insert into @t
values
(1, N'<Key><Name>Adobe</Name><Display>Ado</Display></Key><Key><Name>xyz</Name><Display>yz</Display><Version>1.2</Version></Key>'),
(2, N'<Key><Name></Name><Display>Microsoft</Display><Version>1.1</Version></Key>');
-- The actual query
with cte as (
select t.Id, cast(t.TextData as xml) as [XMLData]
from @t t
)
select c.Id,
k.c.value('./Name[1]', 'varchar(max)') as [Name],
k.c.value('./Display[1]', 'varchar(max)') as [DisplayName],
k.c.value('./Version[1]', 'varchar(max)') as [Version]
from cte c
cross apply c.XMLData.nodes('/Key') k(c);
Different type can be corrected with the in-place cast/convert done in CTE (or equivalent subquery).
Upvotes: 1