SQL FOR XML 生成多个同名节点

SQL FOR XML to generate multiple same name nodes

我正在尝试使用 xml 创建具有相同名称但具有来自 table 中不同列的不同数据的子节点。但是我没有从我构建的查询中得到预期的输出。

谁能告诉我构建此查询的正确方法?

示例 table 和使用的 FOR XML 查询如下:

;WITH Temp(id, name1, name2)
AS
(
    SELECT 1, 'A', 'B' UNION
    SELECT 2, 'C', 'D' UNION
    SELECT 3, 'E', 'F'
)
SELECT
    id
    ,name1 AS [names/name]
    ,name2 AS [names/name]
FROM
    Temp
FOR XML PATH('Data'), TYPE, ROOT('Feed')

输出:

<Feed>
  <Data>
    <id>1</id>
    <names>
      <name>AB</name>
    </names>
  </Data>
  <Data>
    <id>2</id>
    <names>
      <name>CD</name>
    </names>
  </Data>
  <Data>
    <id>3</id>
    <names>
      <name>EF</name>
    </names>
  </Data>
</Feed>

预期输出:

<Feed>
  <Data>
    <id>1</id>
    <names>
      <name>A</name>
      <name>B</name>
    </names>
  </Data>
  <Data>
    <id>2</id>
    <names>
      <name>C</name>
      <name>D</name>
    </names>
  </Data>
  <Data>
    <id>3</id>
      <name>E</name>
      <name>F</name>
    </names>
  </Data>
</Feed>

您可以 select 子查询中的名称

;WITH Temp(id, name1, name2)
AS
(
    SELECT 1, 'A', 'B' UNION
    SELECT 2, 'C', 'D' UNION
    SELECT 3, 'E', 'F'
)
SELECT
    id
    ,(SELECT name 
        FROM (
                SELECT name1 AS name 
                FROM Temp t2 
                WHERE t1.id = t2.id 
                UNION ALL 
                SELECT name2 AS name 
                FROM Temp t2 
                WHERE t1.id = t2.id) AS t 
        FOR XML PATH(''), TYPE) AS names
FROM
    Temp t1
FOR XML PATH('Data'), TYPE, ROOT('Feed')

你可以通过交叉应用很好地做到这一点:

;WITH Temp(id, name1, name2)
AS
(
    SELECT 1, 'A', 'B' UNION
    SELECT 2, 'C', 'D' UNION
    SELECT 3, 'E', 'F'
)
SELECT
    id
    ,x.name AS [names/name]

FROM
    Temp
    CROSS APPLY 
        (VALUES
            (name1),
            (name2)
        ) x (name)
FOR XML PATH('Data'), TYPE, ROOT('Feed')

我想,这应该是非常有效的(至少在 SQL 服务器上工作):

;WITH Temp(id, name1, name2)
AS
(
    SELECT 1, 'A', 'B' UNION
    SELECT 2, 'C', 'D' UNION
    SELECT 3, 'E', 'F'
)
SELECT
    id,
    (
        SELECT
            name1 AS name
            ,null
            ,name2 AS name
        FOR XML PATH(''), TYPE
    ) AS names
FROM
    Temp
FOR XML PATH('Data'), TYPE, ROOT('Feed')