SQL Server : XML 경로 용 - 중첩 / 그룹화
-
11-12-2019 - |
문제
나는 보이는 데이터가있다 :
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
.
SQL Server에 T-SQL 쿼리를 작성하여 다음과 같은 데이터를 반환하고 싶습니다.
<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>
.
다음을 사용하여 XML로 쿼리를 반환하려고 시도했습니다.
FOR XML PATH ('Order'), root ('Root')
.
그러나 각 행에 대한 Order
노드 (총 6 개) 대 각 Per 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')
. 다른 팁
완료 : 하위 선택이없는 솔루션이 있습니다. 큰 테이블을보다 빨리 수행해야합니다.대신 XML의 레벨이있는만큼 테이블을 그룹화하고 grouping_id로 레벨을 식별합니다 ( https://technet.microsoft.com/en-us/library/bb522495 (v= sql.105) .aspx 및 https://docs.microsoft.com/ko/ko/ko-US / SQL / 관계형 데이터베이스 / XML / 사용 - 명시 적 모드 - 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
. 제휴하지 않습니다 StackOverflow