使用 TSQL 如何在按字段分组时从 table return XML?

Using TSQL how can I return XML from a table while grouping by a field?

很难解释,但我会举个例子。假设我有以下 table:

PolicyNo    ClientNo    Name
--------    --------    ----
  123          1        John         
  123          2        Sally
  ABC          3        Alice
  ABC          4        Bob

我想使用 TSQL 和 "FOR XML" 将信息分组到类似的政策编号下,如下所示:

<root>
    <Policy>
        <PolicyNo> 123 </PolicyNo>
        <ClientInfo>
            <ClientNo> 1 </ClientNo>
            <Name> John </Name>
        </ClientInfo>
        <ClientInfo>
            <ClientNo> 2 </ClientNo>
            <Name> Sally </Name>
        </ClientInfo>
    </Policy>
    <Policy>
        <PolicyNo> ABC </PolicyNo>
        <ClientInfo>
            <ClientNo> 3 </ClientNo>
            <Name> Alice </Name>
        </ClientInfo>
        <ClientInfo>
            <ClientNo> 4 </ClientNo>
            <Name> Bob </Name>
        </ClientInfo>
    </Policy>
</root>

我实际上在玩了一会儿之后找到了我自己问题的答案。这是我的解决方案:

declare @T table
(
  PolicyNo varchar(3),
  ClientNo int,
  Name varchar(10)
)

insert into @T values
('123', 1, 'John'),
('123', 2, 'Sally'),
('ABC', 3, 'Alice'),
('ABC', 4, 'Bob')

SELECT 
    T1.PolicyNo AS "PolicyNo",
    cast((SELECT
        T2.ClientNo AS "ClientNo",
        T2.Name AS "Name"
    FROM @T T2
    WHERE T1.PolicyNo=T2.PolicyNo
    FOR XML PATH ('ClientInfo')) as XML)
FROM @T T1
GROUP BY T1.PolicyNo
FOR XML PATH ('Policy'), ROOT ('root')

这只是对你自己的补充,很好的解决方案:

SELECT 
    T1.PolicyNo AS "PolicyNo",
    (SELECT
        T2.ClientNo AS "ClientNo",
        T2.Name AS "Name"
    FROM @T T2
    WHERE T1.PolicyNo=T2.PolicyNo
    FOR XML PATH ('ClientInfo'),TYPE)
FROM @T T1
GROUP BY T1.PolicyNo
FOR XML PATH ('Policy'), ROOT ('root')

没有必要使用 CAST(... AS XML)。只需使用 ,TYPE 强制子 select 被处理为 native XML.

我目前不知道这是否会影响性能(读取为字符串并重新转换为 XML)或者如果引擎足够聪明可以遇到实际上不需要此转换的情况...