How to return XML from SQL Server 2008 that is structured with multiple selections sharing a common parent
Solution 1
Try something like this - it uses FOR XML PATH
and subselects to create the "linked" sub-nodes for a given customer (I limited this to two sub tables - but you should get the "gist" of it and be able to extend it to any number of linked subtables):
SELECT
CustomerID AS '@CustomerID',
CustName AS '@Name',
(SELECT ProductName AS '@productname'
FROM dbo.Products p
WHERE p.CustomerID = c.CustomerID
FOR XML PATH('Product'), TYPE) AS 'Products',
(SELECT HobbyName AS '@hobbyname'
FROM dbo.Hobbies h
WHERE h.CUstomerID = c.CustomerID
FOR XML PATH('Hobby'), TYPE) AS 'Hobbies'
FROM
dbo.Customers c
FOR XML PATH('Customer'), ROOT('Customers')
Gives me an output something like:
<Customers>
<Customer CustomerID="1" Name="Fred">
<Products>
<Product productname="Table" />
<Product productname="Wardrobe" />
<Product productname="Chair" />
</Products>
<Hobbies>
<Hobby hobbyname="Golf" />
<Hobby hobbyname="Swimming" />
</Hobbies>
</Customer>
<Customer CustomerID="2" Name="Sue">
<Products>
<Product productname="CD Player" />
<Product productname="Picture frame" />
</Products>
<Hobbies>
<Hobby hobbyname="Dancing" />
<Hobby hobbyname="Gardening" />
<Hobby hobbyname="Reading" />
</Hobbies>
</Customer>
</Customers>
Solution 2
Using FOR XML RAW
IF OBJECT_ID ('tempdb..#customer') IS NOT NULL DROP TABLE #Customer
IF OBJECT_ID ('tempdb..#product') IS NOT NULL DROP TABLE #product
IF OBJECT_ID ('tempdb..#vehicle') IS NOT NULL DROP TABLE #Vehicle
IF OBJECT_ID ('tempdb..#hobbies') IS NOT NULL DROP TABLE #Hobbies
CREATE TABLE #Customer (id INT,name NVARCHAR(20))
INSERT INTO #customer SELECT 1,'Fred' UNION ALL SELECT 2,'Sue'
CREATE TABLE #product(customer_id INT, name NVARCHAR(20))
INSERT INTO #product
SELECt 1 AS id, 'table' as product
UNION ALL SELECT 1 AS id, 'chair' as product
UNION ALL SELECT 1 AS id, 'wardrobe' as product
UNION ALL SELECT 2 AS id, 'CD Player' as product
UNION ALL SELECT 2 AS id, 'Picture Frame' as product
CREATE TABLE #vehicle(customer_id INT, name NVARCHAR(20),colour NVARCHAR(20))
INSERT INTO #vehicle
SELECt 1 AS id, 'Car' as vehicle,'red' as colour
UNION ALL SELECT 1 AS id, 'bicycle' as vehicle,'Blue' AS colour
UNION ALL SELECT 2 AS id, 'Car' as vehicle, 'Yellow' as colour
CREATE TABLE #hobbies(customer_id INT, name NVARCHAR(20))
INSERT INTO #hobbies
SELECt 1 AS id, 'Golf' as name
UNION ALL SELECT 1 AS id, 'Swimming' as name
UNION ALL SELECT 2 AS id, 'Dancing' as name
UNION ALL SELECT 2 AS id, 'Reading' as name
SELECT
c.id AS id
,c.name AS name
,(SELECT p.name
FROM #product p
WHERE p.customer_id = c.id
FOR XML RAW('Products'),TYPE) AS Products
,(SELECT h.name
FROM #hobbies h
WHERE h.customer_id = c.id
FOR XML RAW('Hobbies'),TYPE) AS Hobbies
,(SELECT v.name,v.colour
FROM #vehicle v
WHERE v.customer_id = c.id
FOR XML RAW('Vehicle'),TYPE) AS Vehicle
FROM #customer c
FOR XML RAW('Customer'), ROOT('Customers')
Solution 3
select
c.customerid,
c.name,
(
select p.productname
from Products as p
where p.customerid = c.customerid
for xml raw('Product'), root('Products'), type
),
(
select h.hobbyname
from Hobbies as h
where h.customerid = c.customerid
for xml raw('Hobby'), root('Hobbies'), type
),
(
select v.name, v.color
from Vehicles as v
where v.customerid = c.customerid
for xml raw('Vehicle'), root('Vehicles'), type
)
from Customers as c
for xml raw('Customer'), root('Customers')
Matt
Updated on November 21, 2020Comments
-
Matt over 3 years
I've tried using "FOR XML PATH", "FOR XML EXPLICIT" and "FOR XML AUTO" but the data is never structured with the correct heirarchy.
Basically, I have one parent table (Customers) and 3 child tables. Each table has a customerid column. There is a one-to-many relationship from the Customers table to each of the 3 child tables.
As a mock example, I have a parent "Customers" table, and I have 3 other tables - Products, Hobbies and Vehicles - all related to the Customers table by a customerid.
What is the SQL code to achieve the following kind of structure -
<Customers> <Customer customerid="1" name="Fred"> <Products> <Product productname="table" /> <Product productname="chair" /> <Product productname="wardrobe" /> </Products> <Hobbies> <Hobby hobbyname="Golf" /> <Hobby hobbyname="Swimming" /> </Hobbies> <Vehicles> <Vehicle name="Car" color="Red" /> <Vehicle name="Bicycle" color="Blue" /> </Vehicles> </Customer> <Customer customerid="2" name="Sue"> <Products> <Product productname="CD player" /> <Product productname="Picture frame" /> </Products> <Hobbies> <Hobby hobbyname="Dancing" /> <Hobby hobbyname="Reading" /> </Hobbies> <Vehicles> <Vehicle name="Car" color="Yellow" /> </Vehicles> </Customer> </Customers>