我有这个XML:
<SearchResponse>
<Data>
<Information>
<Code>Code 1</Code>
<Options>
<Option>
<TID>1</TID>
<Rooms>
<ReturnRoom>
<RoomId>1</RoomId>
<Description>Single</Description>
</ReturnRoom>
<ReturnRoom>
<RoomId>2</RoomId>
<Description>Standard</Description>
</ReturnRoom>
</Rooms>
</Option>
<Option>
<TID>2</TID>
<Rooms>
<ReturnRoom>
<RoomId>1</RoomId>
<Description>Single</Description>
</ReturnRoom>
</Rooms>
</Option>
</Options>
</Information>
</Data>
</SearchResponse>
我如何获得
Code Name TID RoomId Description
---------------------------------------------------
Code 1 Hotel 1 1 1;2 Single;Standard
Code 1 Hotel 1 2 1 Single
答案 0 :(得分:4)
简单的nodes
和value
功能应该足够了:
DECLARE @xml XML = N'<SearchResponse>
<Data>
<Information>
<Code>Code 1</Code>
<Options>
<Option>
<TID>1</TID>
<Rooms>
<ReturnRoom>
<RoomId>1</RoomId>
<Description>Single</Description>
</ReturnRoom>
<ReturnRoom>
<RoomId>2</RoomId>
<Description>Standard</Description>
</ReturnRoom>
</Rooms>
</Option>
<Option>
<TID>2</TID>
<Rooms>
<ReturnRoom>
<RoomId>1</RoomId>
<Description>Single</Description>
</ReturnRoom>
</Rooms>
</Option>
</Options>
</Information>
</Data>
</SearchResponse>';
SELECT b.value('(../../../../Code/text())[1]', 'NVARCHAR(MAX)') AS Code
,b.value('(../../TID/text())[1]', 'NVARCHAR(MAX)') AS TID
,b.value('(./RoomId/text())[1]', 'NVARCHAR(MAX)') AS RoomId
,b.value('(./Description/text())[1]', 'NVARCHAR(MAX)') AS Description
FROM @xml.nodes('/SearchResponse/Data/Information/Options/Option/Rooms/ReturnRoom') AS a(b);
<强> Rextester demo 强>
修改强>
如果你真的需要聚合字符串,你可以使用:
WITH cte AS (
SELECT b.value('(../../../../Code/text())[1]', 'NVARCHAR(MAX)') AS Code
,b.value('(../../TID/text())[1]', 'NVARCHAR(MAX)') AS TID
,b.value('(./RoomId/text())[1]', 'NVARCHAR(MAX)') AS RoomId
,b.value('(./Description/text())[1]', 'NVARCHAR(MAX)') AS Description
FROM @xml.nodes('/SearchResponse/Data/Information/Options/Option/Rooms/ReturnRoom') AS a(b)
)
SELECT Code, TID,
STRING_AGG(RoomId, ';') AS RoomId,
STRING_AGG(Description, ';') AS Description
FROM cte
GROUP BY Code, TID;
这适用于SQL Server 2017+。对于较低版本,您必须使用不同的方法,如XML或CLR函数。
<强> DBFiddle 强>
编辑2:
使用CROSS APPLY
:
WITH cte AS (
SELECT b.value('(../../Code/text())[1]', 'NVARCHAR(MAX)') AS Code
,b.value('(TID/text())[1]', 'NVARCHAR(MAX)') AS TID
,d.value('(RoomId/text())[1]', 'NVARCHAR(MAX)') AS RoomId
,d.value('(Description/text())[1]', 'NVARCHAR(MAX)') AS Description
FROM @xml.nodes('/SearchResponse/Data/Information/Options/Option') AS a(b)
CROSS APPLY a.b.nodes('Rooms/ReturnRoom') AS c(d)
)
SELECT Code, TID, STRING_AGG (RoomId, ';'), STRING_AGG(Description, ';')
FROM cte
GROUP BY Code, TID;
<强> DBFiddle 2 强>