2

3 つのテーブルを保持するデータベースの場合:

  1. 会社
  2. デパートメント
  3. 所属部署の従業員

以下のようなxmlにしたいと思います:

<Companies>
  <Company>
    <CompanyName></CompanyName>
    <CompanyId></CompanyId>
    <..></..>
    <Departments>
       <Name></Name>
       <..></..>
       <Employees>
          <Employee>
             <FirstName></FirstName>
             <LastName></LastName>
             .. .. ..
          </Employee>
          .. .. ..
       </Employees>
    </Departments>
    .. .. ..
  </Company>
  .. .. .. 
</Companies>

会社が繰り返している場合(タグ)、社内の部門が繰り返している場合(タグ)、部門内の従業員が繰り返している場合(タグ)を繰り返すことで、データではなくこれらの要素の数が複数あることを意味します。

関係

  1. Companyとin table にリンクされているin table をDepartment介して関連付けられています。FKDepartmentCompanyIdCompany

  2. Departmentテーブル内にリンクするテーブルEmployeeInDepartment内の「FK」を介して関連付けられています。EmployeeInDepartmentDepartmentIdDepartment

クエリ:

PUBS データベースで以下を実行し、xml を確認します。ID 10 の複数のジョブが含まれます。

select jobs.job_id 'JobId',
job_desc 'Desc',
(
    select emp_id 'EmployeeId',fname 'FirstName',lname 'LastName' from employee where job_id = jobs.job_id for xml path('Emploees'),type
)
from jobs
inner join 
employee on  jobs.job_id = employee.job_id
for xml path('employees')
4

2 に答える 2

3

「ネストされた」ステートメントを実行する必要がありますFOR 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 のNested FOR XML results with SQL Serverを参照してください。もちろん、2 つ以上のレベルを簡単にネストできます...

于 2012-01-18T12:58:43.707 に答える
2

あなたがこれをどのように望んでいるのか完全にはわかりませんが、これはあなたの出発点になるはずです。

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 jobs.job_id = employee.emp_idの行をフィルタリングする where 句を使用して必要な情報のみをクエリし、子ノードで必要な行のみを取得します。

于 2012-01-18T15:31:37.433 に答える