SQL Server : FOR XML PATH - nesting / grouping

后端 未结 2 919
闹比i
闹比i 2020-12-15 17:36

I have data that looks like:

OrderID CustomerID  ItemID  ItemName
10000   1234        111111  Product A
10000   1234        222222  Product B
10000   1234            


        
相关标签:
2条回答
  • 2020-12-15 17:44
    select  
        OrderID,
        CustomerID,
        (
            select 
            ItemID,
            ItemName
            from @Orders rsLineItem
            where rsLineItem.OrderID = rsOrders.OrderID
            for xml path('LineItem'), type
        )
    from (select distinct OrderID, CustomerID from @Orders) rsOrders
    FOR XML PATH ('Order'), root ('Root')
    
    0 讨论(0)
  • 2020-12-15 17:57

    For completion: here is a solution without subselect, that should perform faster for big tables. Instead it groups the table as many times as there are levels in the XML and identifies the level with GROUPING_ID (see https://technet.microsoft.com/en-us/library/bb522495(v=sql.105).aspx and https://docs.microsoft.com/en-us/sql/relational-databases/xml/use-explicit-mode-with-for-xml) :

    with rsOrders as (
      select '10000' OrderID, '1234' CustomerID, '111111' ItemID, 'Product A' ItemName union
      select '10000' orderId, '1234' customerID, '222222' itemID, 'Product B' ItemName union
      select '10000' orderId, '1234' customerID, '333333' itemID, 'Product C' ItemName union
      select '20000' orderId, '5678' customerID, '111111' itemID, 'Product A' ItemName union
      select '20000' orderId, '5678' customerID, '222222' itemID, 'Product B' ItemName union
      select '20000' orderId, '5678' customerID, '333333' itemID, 'Product C' ItemName 
    )
    select case 
             when GROUPING_ID(ItemID) = 0 then 3 
             when GROUPING_ID(OrderID) = 0 then 2 
             else 1 
             end as tag,
           case 
               when GROUPING_ID(ItemID) = 0 then 2 
             when GROUPING_ID(OrderID) = 0 then 1 
             else null
           end as parent,
           null       as 'Root!1',
           OrderID    as 'Order!2!OrderID!element', 
           CustomerID as 'Order!2!CustomerID!element', 
           ItemID     as 'LineItem!3!ItemID!element', 
           ItemName   as 'LineItem!3!ItemName!element'
      from rsOrders
     group by grouping sets ((), (OrderID, CustomerID), (OrderID, CustomerID, ItemID, ItemName))
     order by OrderID, CustomerID, ItemID, ItemName
       for xml explicit, type
    
    0 讨论(0)
提交回复
热议问题