Sql server 生成xml时复制了节点
下面是我在生成所需格式的xml时遇到的问题(我有重复的节点):我有一个记录实体修改的表,可以一次对多个列进行修改。例如,我有以下@my_表(我们可以看到“entity 2”上的“modif 3”同时更改了2列,即第5列和第6列): 我必须编写一个xml select,它返回其中一个实体的所有更改。预期的xml格式如下所示:Sql server 生成xml时复制了节点,sql-server,xml,tsql,Sql Server,Xml,Tsql,下面是我在生成所需格式的xml时遇到的问题(我有重复的节点):我有一个记录实体修改的表,可以一次对多个列进行修改。例如,我有以下@my_表(我们可以看到“entity 2”上的“modif 3”同时更改了2列,即第5列和第6列): 我必须编写一个xml select,它返回其中一个实体的所有更改。预期的xml格式如下所示: <history> <id_entity></id_entity> <modifs> <modif>
<history>
<id_entity></id_entity>
<modifs>
<modif>
<id_modif></id_modif>
<details>
<column></column>
<value></value>
</details>
<details></details>
<details></details>
...
</modif>
<modif></modif>
<modif></modif>
....
</modifs>
</history>
注意:我找到了一个解决方法,我向老板展示了一个不同的xml结构,但这是一个非常长的过程的结束,这个过程太长,无法修改
非常感谢 试试挖:
SELECT
t.id_entity,
(
SELECT
p.id_modif,
(
SELECT
h.id_column,
h.new_value
FROM @my_table h
WHERE p.id_modif = h.id_modif
FOR XML PATH('details'), TYPE
)
FROM @my_table AS p
WHERE t.id_entity = p.id_entity
GROUP BY p.id_modif
FOR XML PATH('modif'), TYPE
) AS modifs
FROM @my_table AS t
WHERE t.id_entity = @id_entity
GROUP BY t.id_entity
FOR XML PATH('history'), type
<history>
<id_entity>entity 1</id_entity>
<modifs>
<modif>
<id_modif>modif 1</id_modif>
<details>
<column>column 4</columns>
<value>coucou</value>
</details>
</modif>
</modifs>
</history>
<history>
<id_entity>entity 2</id_entity>
<modifs>
<modif>
<id_modif>modif 2</id_modif>
<details>
<column>column 1</column>
<value>papa</value>
</details>
</modif>
<modif>
<id_modif>modif 3</id_modif>
<details>
<column>column 5</column>
<value>blabla</value>
</details>
<details>
<column>column 6</column>
<value>toto</value>
</details>
</modif>
</modifs>
</history>
-- What I Got ('modif 3' node is duplicated because in @my_table I have 2 rows with 'modif 3') :
<history>
<id_entity>entity 2</id_entity>
<modifs>
<modif>
<id_modif>modif 2</id_modif>
<details column 1 />
</modif>
<modif>
<id_modif>modif 3</id_modif>
<details columns 5 />
<details columns 6 />
</modif>
<modif>
<id_modif>modif 3</id_modif>
<details columns 5 />
<details columns 6 />
</modif>
</modifs>
</history>
-- What I wanted (only one node 'modif 3' with 2 'details' nodes):
<history>
<id_entity>entity 2</id_entity>
<modifs>
<modif>
<id_modif>modif 2</id_modif>
<details column 1 />
</modif>
<modif>
<id_modif>modif 3</id_modif>
<details columns 5 />
<details columns 6 />
</modif>
</modifs>
</history>
declare @my_table table(
id_entity varchar(10),
id_modif varchar(10),
id_column varchar(15),
new_value varchar(15))
insert into @my_table
select 'entity 1', 'modif 1', 'column 4', 'coucou' union
select 'entity 2', 'modif 2', 'column 1', 'papa' union
select 'entity 2', 'modif 3', 'column 5', 'blabla' union
select 'entity 2', 'modif 3', 'column 6', 'toto'
declare @id_entity varchar(10) = 'entity 2'
select
@id_entity as 'id_entity',
(select
parent.id_modif as 'id_modif',
(select distinct
child.id_column as 'column',
child.new_value as 'value'
from @my_table child
where child.id_entity = @id_entity
and child.id_modif = parent.id_modif
for xml path ('details'), type ) '*'
from @my_table parent
where parent.id_entity = @id_entity
for xml path ('modif'), root('modifs'), type ) '*'
for xml path ('history'), type
SELECT
t.id_entity,
(
SELECT
p.id_modif,
(
SELECT
h.id_column,
h.new_value
FROM @my_table h
WHERE p.id_modif = h.id_modif
FOR XML PATH('details'), TYPE
)
FROM @my_table AS p
WHERE t.id_entity = p.id_entity
GROUP BY p.id_modif
FOR XML PATH('modif'), TYPE
) AS modifs
FROM @my_table AS t
WHERE t.id_entity = @id_entity
GROUP BY t.id_entity
FOR XML PATH('history'), type