سؤال

لدي البيانات التي تبدو مثل:

OrderID CustomerID  ItemID  ItemName
10000   1234        111111  Product A
10000   1234        222222  Product B
10000   1234        333333  Product C
20000   5678        111111  Product A
20000   5678        222222  Product B
20000   5678        333333  Product C

أريد أن أكتب استعلام تي سكل في سكل سيرفر لإرجاع البيانات مثل هذا:

<Root>
  <Order>
    <OrderID>10000</OrderID>
    <CustomerID>1234</CustomerID>
    <LineItem>
      <ItemID>11111</ItemId>
      <ItemName>Product A</ItemName>
    </LineItem>
    <LineItem>
      <ItemID>22222</ItemId>
      <ItemName>Product B</ItemName>
    </LineItem>
    <LineItem>
      <ItemID>33333</ItemId>
      <ItemName>Product B</ItemName>
    </LineItem>
  </Order>
  <Order>
    <OrderID>20000</OrderID>
    <CustomerID>5678</CustomerID>
    <LineItem>
      <ItemID>11111</ItemId>
      <ItemName>Product A</ItemName>
    </LineItem>
    <LineItem>
      <ItemID>22222</ItemId>
      <ItemName>Product B</ItemName>
    </LineItem>
    <LineItem>
      <ItemID>33333</ItemId>
      <ItemName>Product B</ItemName>
    </LineItem>
  </Order>
</Root>

لقد حاولت إرجاع الاستعلام في شمل باستخدام:

FOR XML PATH ('Order'), root ('Root')

ولكن هذا يعطيني Order عقدة لكل صف (6 في المجموع) مقابل.مجرد عقدة النظام لكل orderId (2 في المجموع).

أي أفكار?

هل كانت مفيدة؟

المحلول

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')

نصائح أخرى

للإنجاز:إليك حل بدون تحديد فرعي ، يجب أن يعمل بشكل أسرع للجداول الكبيرة.بدلا من ذلك ، يقوم بتجميع الجدول عدة مرات حيث توجد مستويات في شمل ويحدد المستوى باستخدام معرف التجميع (انظر https://technet.microsoft.com/en-us/library/bb522495 (ت = سكل. 105). أسبكس و 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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top