使用TSQL在按字段分组时如何从表返回XML?

使用TSQL在按字段分组时如何从表返回XML?,xml,tsql,group-by,for-xml-path,Xml,Tsql,Group By,For Xml Path,这很难解释,但我会举个例子。假设我有下表: PolicyNo ClientNo Name -------- -------- ---- 123 1 John 123 2 Sally ABC 3 Alice ABC 4 Bob 我想使用TSQL和“FOR XML”将信息分组到类似的策略编号下,如下所示: <

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

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>

123
1.
约翰
2.
俏皮话
基础知识
3.
爱丽丝
4.
上下快速移动

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

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

这只是对您自己的伟大解决方案的补充:

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(…作为XML)
。只需使用
,键入
,即可强制将子选择作为本机XML处理

我目前不知道这是否会影响性能(读作字符串,重新转换为XML),或者引擎是否足够聪明,是否实际上不需要这种转换