简体   繁体   中英

SQL Server FOR XML with nested sub-select

The following sql code

SELECT  
 b.GivenName [Individual/Name/FirstName] ,
 b.FamilyName [Individual/Name/LastName] ,
 b.Address_Country [Individual/Address/CountryCode] ,
 b.AddressFree [Individual/Address/AddressFree]
FROM dbo.stage_Clients_Merge b
WHERE b.DWHClientNo = @dwhclientNo
FOR XML PATH('Owner'), TYPE

will generate an xml fragment

<Owner>
 <Individual>
  <Name>
   <FirstName>Bob</FirstName>
   <LastName>Smith</LastName>
  </Name>
  <Address>
    <CountryCode>US</CountryCode>
    <AddressFree>123,Utah</AddressFree>
  </Address>
 </Individual>
</Owner>

If I extend this query to include a sub-query to return, for example, all the orders associated with a individual using the following:

  (SELECT
     c.OrderIdentificationNumber [Individual/OrderNumber]
  FROM
   dbo.stage_Customer_Orders c
  WHERE
    c.CustomerNo = b.masterClient
  FOR
   XML PATH(''), TYPE)

I will get the individual section twice. How can I combine the two to return the following?

<Owner>
 <Individual>
  <OrderNo>12345</OrderNo>
  <OrderNo>23456</OrderNo>
   <Name>
    <FirstName>Bob</FirstName>
    <LastName>Smith</LastName>
   </Name>
   <Address>
    <CountryCode>US</CountryCode>
    <AddressFree>123,Utah</AddressFree>
  </Address>
 </Individual>
</Owner>

You can use a subquery and [data()] to just get the column values with no additional nesting - then use path as before:

SELECT  
    (SELECT      c.OrderIdentificationNumber as [data()]
     FROM dbo.stage_Customer_Orders c
     WHERE c.CustomerNo = b.masterClient
     For XML Path('OrderNo'), type) as [Individual],
     b.GivenName [Individual/Name/FirstName] ,
     b.FamilyName [Individual/Name/LastName] ,
     b.Address_Country [Individual/Address/CountryCode] ,
     b.AddressFree [Individual/Address/AddressFree]
FROM dbo.stage_Clients_Merge b
WHERE b.DWHClientNo = @dwhclientNo
FOR XML PATH('Owner'), TYPE

Try it like this

I set up a mock-up scenario for stand-alone solutions. Next time you have a question, you might try this on your own. This makes it much easier to understand your issue and create a fully working and testable solution for it.

DECLARE @stage_Clients_Merge TABLE(ID INT,FirstName VARCHAR(100),LastName VARCHAR(100),CountryCode VARCHAR(100),AdressFree VARCHAR(100));
INSERT INTO @stage_Clients_Merge VALUES
 (1,'Bob','Smith','US','123/Utah')
,(2,'Jim','Doh','US','123/Maryland');


DECLARE @orders TABLE(CustomerID INT, OrderNo INT)
INSERT INTO @orders VALUES
 (1,11111),(1,12222)
,(2,21111),(2,22222);

SELECT (SELECT OrderNo FROM @orders WHERE CustomerID=b.ID FOR XML PATH(''),TYPE) AS Individual
      ,FirstName AS [Individual/Name/FirstName]
      ,LastName AS [Individual/Name/LastName]
      ,CountryCode AS [Individual/Address/CountryCode]
      ,AdressFree AS [Individual/Address/AdressFree] 
FROM @stage_Clients_Merge AS b
FOR XML PATH('Owner');

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM