Reputation: 89
I have one table in following format.
I want data in XML format per Employee using SQL query as below
<Employee>
<EmployeeID>1</EmployeeID>
<FirstName>Jon</FirstName>
<LastName>Snow</LastName>
<City>North of the wall</City>
<Age>28</Age>
<Gender>Male</Male>
</Employee>
<Employee>
<EmployeeID>2</EmployeeID>
<FirstName>Arya</FirstName>
<LastName>Stark</LastName>
<City>Winterfell</City>
<Age>14</Age>
<Gender>Female</Male>
</Employee>
I have tried using query,
SELECT DISTINCT EmployeeID ,(
SELECT
EmployeeID,
(SELECT PDFKey ,
Replace(Value,char(CAST(0x001A as int)),'') as Value FROM TempData EE WHERE E.EmployeeID =EE.EmployeeID FOR XML PATH(''),
TYPE, ELEMENTS)
AS Employee
FROM
TempData E WHERE o.EmployeeID =E.EmployeeID
GROUP BY EmployeeID
FOR XML AUTO, ELEMENTS
) AS XMLtag FROM TempData O
But it gives data in format like,
<E>
<EmployeeID>1</EmployeeID>
<Employee>
<PDFKey>FirstName</PDFKey>
<Value>Jon</Value>
<PDFKey>LastName</PDFKey>
<Value>Snow</Value>
<PDFKey>City</PDFKey>
<Value>North of the wall</Value>
<PDFKey>Age</PDFKey>
<Value>28</Value>
<PDFKey>Gender</PDFKey>
<Value>Male</Value>
</Employee>
</E>
And I want one row per employee which will have 2 columns, EmployeeID and XMLdata.
Please refer image below for expected output, enter image description here
Upvotes: 0
Views: 2433
Reputation: 15977
You can use PIVOT + FOR XML PATH:
SELECT *
FROM Employee
PIVOT (
MAX([Value]) FOR PDFKey IN ([FirstName],[LastName],[City],[Age],[Gender])
) as u
FOR XML PATH('Employee'), TYPE
Output:
<Employee>
<EmployeeID>1</EmployeeID>
<FirstName>Jon</FirstName>
<LastName>Snow</LastName>
<City>North of the wall</City>
<Age>28</Age>
<Gender>Male</Gender>
</Employee>
<Employee>
<EmployeeID>2</EmployeeID>
<FirstName>Arya</FirstName>
<LastName>Stark</LastName>
<City>Winterfell</City>
<Age>14</Age>
<Gender>Female</Gender>
</Employee>
After pivoting you will get table like this:
EmployeeID FirstName LastName City Age Gender
1 Jon Snow North of the wall 28 Male
2 Arya Stark Winterfell 14 Female
After that you add FOR XML with PATH mode
In PATH mode, column names or column aliases are treated as XPath expressions. These expressions indicate how the values are being mapped to XML. Each XPath expression is a relative XPath that provides the item type., such as the attribute, element, and scalar value, and the name and hierarchy of the node that will be generated relative to the row element.
Also I have added TYPE
SQL Server support for the xml (Transact-SQL) enables you to optionally request that the result of a FOR XML query be returned as xml data type by specifying the TYPE directive.
EDIT
;WITH cte AS (
SELECT *
FROM Employee
PIVOT (
MAX([Value]) FOR PDFKey IN ([FirstName],[LastName],[City],[Age],[Gender])
) as u
)
SELECT e.EmployeeID,
(SELECT *
FROM cte
WHERE EmployeeID = e.EmployeeID
FOR XML PATH('Employee'), TYPE) as XMLData
FROM cte e
Output:
EmployeeID XMLData
1 <Employee><EmployeeID>1</EmployeeID><FirstName>Jon</FirstName><LastName>Snow</LastName><City>North of the wall</City><Age>28</Age><Gender>Male</Gender></Employee>
2 <Employee><EmployeeID>2</EmployeeID><FirstName>Arya</FirstName><LastName>Stark</LastName><City>Winterfell</City><Age>14</Age><Gender>Female</Gender></Employee>
Upvotes: 3