Reputation: 137
I need an XML from the following two tables provided below. The problem I am having is that I am not able to separate out the attributes for each project in the XML.
declare @A table
(
PROJECT_ID varchar(10),
SITE_ID varchar(10)
);
declare @B table
(
PROJECT_ID varchar(10),
ATTRIBUTE_NAME varchar(15)
)
insert into @A values
('PROJECT1', 'A'),
('PROJECT2', 'B');
insert into @B values
('PROJECT1', 'PERSONID'),
('PROJECT1', 'GIVENNAME'),
('PROJECT1', 'MIDDLENAME'),
('PROJECT1', 'FAMILYNAME'),
('PROJECT1', 'DATEOFBIRTH'),
('PROJECT1', 'SEX'),
('PROJECT2', 'PERSON_ID'),
('PROJECT2', 'GIVEN_NAME'),
('PROJECT2', 'MIDDLE_NAME'),
('PROJECT2', 'FAMILY_NAME'),
('PROJECT2', 'DATEOF_BIRTH');
The XML result I want is:
<SITEID>A</SITEID>
<Project>
<Name>PROJECT 1</Name>
<Columns>
<PracticeColumn>
<Name>PERSONID</Name>
</PracticeColumn>
<PracticeColumn>
<Name>GIVENNAME</Name>
</PracticeColumn>
<PracticeColumn>
<Name>MIDDLENAME</Name>
</PracticeColumn>
<PracticeColumn>
<Name>FAMILYNAME</Name>
</PracticeColumn>
<PracticeColumn>
<Name>DATEOFBIRTH</Name>
</PracticeColumn>
<PracticeColumn>
<Name>SEX</Name>
</PracticeColumn>
</Columns>
</Project>
<Project>
<Name>PROJECT 2</Name>
<Columns>
<PracticeColumn>
<Name>PERSON_ID</Name>
</PracticeColumn>
<PracticeColumn>
<Name>GIVEN_NAME</Name>
</PracticeColumn>
<PracticeColumn>
<Name>MIDDLE_NAME</Name>
</PracticeColumn>
<PracticeColumn>
<Name>FAMILY_NAME</Name>
</PracticeColumn>
<PracticeColumn>
<Name>DATEOF_BIRTH</Name>
</PracticeColumn>
</Columns>
</Project>
Note: Each project can have a different set of attributes. So the XML has to cater to that.
This is what I have attempted:
SELECT a.PROJECT_ID as Name,
(SELECT
ATTRIBUTE_NAME as Name
FROM @A a
INNER JOIN @B b ON b.PROJECT_ID = a.PROJECT_ID
--WHERE a.SITE_ID = 'A'
FOR XML PATH ('PracticeColumn'), Root('Columns'),TYPE
)
FROM @A a
--WHERE .SITE_ID = 'A'
FOR XML PATH ('Project'),TYPE
And got the result below. Each Project in the xml has all attributes from all Projects.
<Project>
<Name>PROJECT1</Name>
<Columns>
<PracticeColumn>
<Name>PERSONID</Name>
</PracticeColumn>
<PracticeColumn>
<Name>GIVENNAME</Name>
</PracticeColumn>
<PracticeColumn>
<Name>MIDDLENAME</Name>
</PracticeColumn>
<PracticeColumn>
<Name>FAMILYNAME</Name>
</PracticeColumn>
<PracticeColumn>
<Name>DATEOFBIRTH</Name>
</PracticeColumn>
<PracticeColumn>
<Name>SEX</Name>
</PracticeColumn>
<PracticeColumn>
<Name>PERSON_ID</Name>
</PracticeColumn>
<PracticeColumn>
<Name>GIVEN_NAME</Name>
</PracticeColumn>
<PracticeColumn>
<Name>MIDDLE_NAME</Name>
</PracticeColumn>
<PracticeColumn>
<Name>FAMILY_NAME</Name>
</PracticeColumn>
<PracticeColumn>
<Name>DATEOF_BIRTH</Name>
</PracticeColumn>
</Columns>
</Project>
<Project>
<Name>PROJECT2</Name>
<Columns>
<PracticeColumn>
<Name>PERSONID</Name>
</PracticeColumn>
<PracticeColumn>
<Name>GIVENNAME</Name>
</PracticeColumn>
<PracticeColumn>
<Name>MIDDLENAME</Name>
</PracticeColumn>
<PracticeColumn>
<Name>FAMILYNAME</Name>
</PracticeColumn>
<PracticeColumn>
<Name>DATEOFBIRTH</Name>
</PracticeColumn>
<PracticeColumn>
<Name>SEX</Name>
</PracticeColumn>
<PracticeColumn>
<Name>PERSON_ID</Name>
</PracticeColumn>
<PracticeColumn>
<Name>GIVEN_NAME</Name>
</PracticeColumn>
<PracticeColumn>
<Name>MIDDLE_NAME</Name>
</PracticeColumn>
<PracticeColumn>
<Name>FAMILY_NAME</Name>
</PracticeColumn>
<PracticeColumn>
<Name>DATEOF_BIRTH</Name>
</PracticeColumn>
</Columns>
</Project>
Upvotes: 0
Views: 45
Reputation: 67311
You need a correlated sub-query like here. You do not JOIN them, but use an appropriate WHERE-clause:
declare @A table
(
PROJECT_ID varchar(10),
SITE_ID varchar(10)
);
declare @B table
(
PROJECT_ID varchar(10),
ATTRIBUTE_NAME varchar(15)
)
insert into @A values
('PROJECT1', 'A'),
('PROJECT2', 'B');
insert into @B values
('PROJECT1', 'PERSONID'),
('PROJECT1', 'GIVENNAME'),
('PROJECT1', 'MIDDLENAME'),
('PROJECT1', 'FAMILYNAME'),
('PROJECT1', 'DATEOFBIRTH'),
('PROJECT1', 'SEX'),
('PROJECT2', 'PERSON_ID'),
('PROJECT2', 'GIVEN_NAME'),
('PROJECT2', 'MIDDLE_NAME'),
('PROJECT2', 'FAMILY_NAME'),
('PROJECT2', 'DATEOF_BIRTH');
--The query
SELECT SITE_ID AS SITEID
,(
SELECT a2.PROJECT_ID AS [Name]
,(
SELECT b.ATTRIBUTE_NAME AS [PracticeColumn/Name]
FROM @B b
WHERE b.PROJECT_ID=a2.PROJECT_ID
FOR XML PATH(''),TYPE
) AS [Columns]
FROM @A a2
WHERE a2.SITE_ID=a.SITE_ID
FOR XML PATH('Project'),TYPE
)
FROM @A a
GROUP BY SITE_ID
FOR XML PATH('');
The result
<SITEID>A</SITEID>
<Project>
<Name>PROJECT1</Name>
<Columns>
<PracticeColumn>
<Name>PERSONID</Name>
</PracticeColumn>
<PracticeColumn>
<Name>GIVENNAME</Name>
</PracticeColumn>
<PracticeColumn>
<Name>MIDDLENAME</Name>
</PracticeColumn>
<PracticeColumn>
<Name>FAMILYNAME</Name>
</PracticeColumn>
<PracticeColumn>
<Name>DATEOFBIRTH</Name>
</PracticeColumn>
<PracticeColumn>
<Name>SEX</Name>
</PracticeColumn>
</Columns>
</Project>
<SITEID>B</SITEID>
<Project>
<Name>PROJECT2</Name>
<Columns>
<PracticeColumn>
<Name>PERSON_ID</Name>
</PracticeColumn>
<PracticeColumn>
<Name>GIVEN_NAME</Name>
</PracticeColumn>
<PracticeColumn>
<Name>MIDDLE_NAME</Name>
</PracticeColumn>
<PracticeColumn>
<Name>FAMILY_NAME</Name>
</PracticeColumn>
<PracticeColumn>
<Name>DATEOF_BIRTH</Name>
</PracticeColumn>
</Columns>
</Project>
Some remarks
I did not know how you want to include the <SITEID>
into your XML. The expected result is not complete in this point of view. So I use three levels of correlated sub-queries. but I think the <SITEID>
was better included into the <Project>
-element or might be an Xml-attribute like here <Project SITEID="A">
. You might want to group all projects of a site within the <SITEID>
too. This is up to you.
Upvotes: 1