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')
我正在尝试使用 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')