Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL Server 2005-TSQL For Xml查询以获取分组的部门和员工_Xml_Sql Server 2005_Nested_For Xml - Fatal编程技术网

SQL Server 2005-TSQL For Xml查询以获取分组的部门和员工

SQL Server 2005-TSQL For Xml查询以获取分组的部门和员工,xml,sql-server-2005,nested,for-xml,Xml,Sql Server 2005,Nested,For Xml,对于包含3个表的数据库: 公司 部门 雇员部门 我想创建一个如下所示的xml: <Companies> <Company> <CompanyName></CompanyName> <CompanyId></CompanyId> <..></..> <Departments> <Name></Name>

对于包含3个表的数据库:

公司 部门 雇员部门 我想创建一个如下所示的xml:

<Companies>
  <Company>
    <CompanyName></CompanyName>
    <CompanyId></CompanyId>
    <..></..>
    <Departments>
       <Name></Name>
       <..></..>
       <Employees>
          <Employee>
             <FirstName></FirstName>
             <LastName></LastName>
             .. .. ..
          </Employee>
          .. .. ..
       </Employees>
    </Departments>
    .. .. ..
  </Company>
  .. .. .. 
</Companies>
您需要对XML语句执行嵌套操作——这应该会提供您所需要的内容

SELECT
   (some 'Company' columns),
   (SELECT
       (some 'Department' columns),
       (SELECT
           (some 'Employee' columns),
        FROM dbo.EmployeeInDepartment e
        WHERE e.DepartmentId = d.DepartmentId
        FOR XML PATH('Employee'), TYPE
       ) AS 'Employees'
    FROM dbo.Department d
    WHERE d.CompanyId = c.CompanyId
    FOR XML PATH('Department'), TYPE
   ) AS 'Departments'
FROM dbo.Company c
FOR XML PATH('Company'), ROOT('Companies')

参见Richard Dingwall的例子,展示了如何做到这一点。当然,您可以轻松嵌套两个以上的级别…

不完全确定您希望如何嵌套,但这应该给您一个开始

declare @jobs table
(
  job_id int,
  job_desc varchar(10)
)

declare @employee table
(
  emp_id int,
  fname varchar(10),
  lname varchar(10),
  job_id int
)

insert into @jobs values
(1, 'Job 1'),
(2, 'Job 2')

insert into @employee values
(1, 'first 1', 'last 1', 1),
(2, 'first 2', 'last 2', 1),
(3, 'first 3', 'last 3', 2)

select employee.emp_id 'EmployeeId',
       employee.fname 'FirstName',
       employee.lname 'LastName',
       (
        select jobs.job_id 'JobId',
               jobs.job_desc 'Desc'
        from @jobs jobs
        where jobs.job_id = employee.emp_id
        for xml path('jobs'),type        
       )
from @employee employee
for xml path('employees')
结果:

<employees>
  <EmployeeId>1</EmployeeId>
  <FirstName>first 1</FirstName>
  <LastName>last 1</LastName>
  <jobs>
    <JobId>1</JobId>
    <Desc>Job 1</Desc>
  </jobs>
</employees>
<employees>
  <EmployeeId>2</EmployeeId>
  <FirstName>first 2</FirstName>
  <LastName>last 2</LastName>
  <jobs>
    <JobId>2</JobId>
    <Desc>Job 2</Desc>
  </jobs>
</employees>
<employees>
  <EmployeeId>3</EmployeeId>
  <FirstName>first 3</FirstName>
  <LastName>last 3</LastName>
</employees>

您不应该将所有表的每个部分都连接起来。主查询仅查询根级别所需的信息,子查询仅使用where子句查询所需的信息,where子句where jobs.job_id=employee.emp_id过滤子查询中的行,以便只在子节点中获得所需的行。

您应该使用for xml path,我认为您会找到所有的行您需要和。@MikaelEriksson您好,mikael,是的,我使用的是xml路径模式,只是公司的部门没有按顺序排列。公司id=1的第一个记录是3,其次是公司id为2,下一步是使用公司id 1,因此当我运行查询时,我会得到两个具有相同公司id的公司标记。如果您可以发布您的查询,这将非常有用。@MikaelEriksson我当然可以。很抱歉,该图表会在过程中提供更多帮助。您的查询和对问题的描述会将此变成一个问题。现在看起来更像是有人能帮我做这件事了:。这对我来说非常有效。选择jobs.job_id'JobId',job_desc'desc',选择emp_id'EmployeeId',fname'FirstName',lname'LastName'from employee,其中job_id=jobs.job_id代表xml路径'employee',从jobs代表xml路径'Employees'输入'Employees'
<employees>
  <EmployeeId>1</EmployeeId>
  <FirstName>first 1</FirstName>
  <LastName>last 1</LastName>
  <jobs>
    <JobId>1</JobId>
    <Desc>Job 1</Desc>
  </jobs>
</employees>
<employees>
  <EmployeeId>2</EmployeeId>
  <FirstName>first 2</FirstName>
  <LastName>last 2</LastName>
  <jobs>
    <JobId>2</JobId>
    <Desc>Job 2</Desc>
  </jobs>
</employees>
<employees>
  <EmployeeId>3</EmployeeId>
  <FirstName>first 3</FirstName>
  <LastName>last 3</LastName>
</employees>