Reputation: 59
Trying to write a SQL Server 2008 XML query. I've simplified my example here, but given this data:
create table #parentinfo (name varchar(50), city varchar(50), state varchar(50))
insert #parentinfo values ('joe', 'yonkers', 'ny')
insert #parentinfo values ('sue', 'sacremento', 'ca')
-- parentname is foreign key to name field in #parentinfo
create table #childinfo (parentname varchar(50), childxml xml)
insert #childinfo values ('joe', '<child>mary</child><child>ben</child>')
insert #childinfo values ('sue', '<child>sally</child><child>roger</child>')
I need to output XML that looks like this:
<parentinfo>
<parent>
<name>joe</name>
<city>yonkers</city>
<state>ny</state>
<children>
<child>mary</child>
<child>ben</child>
</children>
</parent>
<parent>
<name>sue</name>
<city>sacremento</city>
<state>ca</state>
<children>
<child>sally</child>
<child>roger</child>
</children>
</parent>
</parentinfo>
This query does that:
select name,
city,
state,
(select childxml
from #childinfo c
where c.parentname = p.name
--for xml auto, type, elements
) as 'children'
from #parentinfo p
group by name, city, state
for xml path('parent')
However, I have problems when one of the parents has an extra row in childinfo table. Add this row to the table:
insert #childinfo values ('joe', '<child>chucky</child><child>pebbles</child>')
And my query blows up saying that subquery returns more than 1 value. I need to handle this scenario. Does anyone know how to resolve?
Thanks.
Upvotes: 5
Views: 12842
Reputation: 138960
select name,
city,
state,
(select childxml as '*'
from #childinfo c
where c.parentname = p.name
for xml path(''), type
) as 'children'
from #parentinfo p
group by name, city, state
for xml path('parent')
Result:
<parent>
<name>joe</name>
<city>yonkers</city>
<state>ny</state>
<children>
<child>mary</child>
<child>ben</child>
<child>chucky</child>
<child>pebbles</child>
</children>
</parent>
<parent>
<name>sue</name>
<city>sacremento</city>
<state>ca</state>
<children>
<child>sally</child>
<child>roger</child>
</children>
</parent>
Upvotes: 6
Reputation: 754268
If you had a "regular" child table - with just a name for the child - and not an XML fragment, you could use this query to get exactly what you're looking for:
create table #parentinfo (name varchar(50), city varchar(50), state varchar(50))
insert #parentinfo values ('joe', 'yonkers', 'ny')
insert #parentinfo values ('sue', 'sacremento', 'ca')
-- parentname is foreign key to name field in #parentinfo
create table #childinfo (parentname varchar(50), childname VARCHAR(50))
insert #childinfo values ('joe', 'mary')
insert #childinfo values ('joe', 'ben')
insert #childinfo values ('sue', 'sally')
insert #childinfo values ('sue', 'roger')
insert #childinfo values ('joe', 'chucky')
insert #childinfo values ('joe', 'pebbles')
select name,
city,
state,
(select childname as 'child'
from #childinfo c
where c.parentname = p.name
order by childname
for xml PATH(''), type
) as 'children'
from #parentinfo p
group by name, city, state
for xml path('parent'), root('parentinfo')
The resulting output is:
<parentinfo>
<parent>
<name>joe</name>
<city>yonkers</city>
<state>ny</state>
<children>
<child>ben</child>
<child>chucky</child>
<child>mary</child>
<child>pebbles</child>
</children>
</parent>
<parent>
<name>sue</name>
<city>sacremento</city>
<state>ca</state>
<children>
<child>roger</child>
<child>sally</child>
</children>
</parent>
</parentinfo>
Upvotes: 10