Search code examples
sql-serverdatabaset-sqlfor-xml

T SQL For XML PATH Group By as Attribute or Element


I have been working on the T-SQL FOR XML with PATH Mode to create a Hierarchy based on the group by field. Below is my query and output. Pls help me with your valuable suggestions. Thank you. Good Day!!!

select e.department_id AS [@DepartmentID],
d.DEPARTMENT_NAME AS [@DepartmentName],
e.EMPLOYEE_ID AS [EmployeeInfo/EmployeeID],
e.FIRST_NAME AS [EmployeeInfo/FirstName],
e.LAST_NAME AS [EmployeeInfo/LastName]
from employees e
JOIN departments d 
ON e.department_id = d.department_id
GROUP BY e.department_id,d.DEPARTMENT_NAME,
e.EMPLOYEE_ID,e.FIRST_NAME,e.LAST_NAME
FOR XML PATH ('Department'), ROOT ('Departments')

Output:

 <Departments>
  <Department DepartmentID="10">
    <EmployeeInfo>
      <EmployeeID>111</EmployeeID>
      <FirstName>John</FirstName>
      <LastName>Chen</LastName>
    </EmployeeInfo>
  </Department>
  <Department DepartmentID="10">
    <EmployeeInfo>
      <EmployeeID>201</EmployeeID>
      <FirstName>steven</FirstName>
      <LastName>Whalen</LastName>
    </EmployeeInfo>
  </Department>
  <Department DepartmentID="30">
    <EmployeeInfo>
      <EmployeeID>105</EmployeeID>
      <FirstName>ANIRUDH</FirstName>
      <LastName>RAMESH</LastName>
    </EmployeeInfo>
  </Department>
  <Department DepartmentID="30">
    <EmployeeInfo>
      <EmployeeID>115</EmployeeID>
      <FirstName>Den</FirstName>
      <LastName>Raphaely</LastName>
    </EmployeeInfo>
  </Department>
<Departments>

Desired Output is :

<Departments>
  <Department DepartmentID="10">
    <EmployeeInfo>
      <EmployeeID>111</EmployeeID>
      <FirstName>John</FirstName>
      <LastName>Chen</LastName>
    </EmployeeInfo>
    <EmployeeInfo>
      <EmployeeID>201</EmployeeID>
      <FirstName>steven</FirstName>
      <LastName>Whalen</LastName>
    </EmployeeInfo>
  </Department>
  <Department DepartmentID="30">
    <EmployeeInfo>
      <EmployeeID>105</EmployeeID>
      <FirstName>ANIRUDH</FirstName>
      <LastName>RAMESH</LastName>
    </EmployeeInfo>
    <EmployeeInfo>
      <EmployeeID>115</EmployeeID>
      <FirstName>Den</FirstName>
      <LastName>Raphaely</LastName>
    </EmployeeInfo>
  </Department>
<Departments>

Solution

  • You could use TYPE for nested xml

    SELECT 
          d.department_id AS [@DepartmentID],
          d.DEPARTMENT_NAME AS [@DepartmentName], 
          (
             SELECT 
                    e.EMPLOYEE_ID AS EmployeeID,
                    e.FIRST_NAME AS [FirstName],
                    e.LAST_NAME AS [LastName]  
             FROM employees e
             WHERE e.department_id = d.department_id
             FOR XML PATH ('EmployeeInfo'), TYPE
          )
    FROM departments d 
    FOR XML PATH ('Department'), ROOT ('Departments')