FOR XML in SQL 服务器:基于列公共值的元素
FOR XML in SQL Server: Elements based on common values of columns
我正在使用 FOR XML 从 SQL 查询中创建一个 XML 文件。我希望元素基于特定列的公共值,在本例中为 "location":
location team score
Adelong SFP 104
Adelong LIB 189
Adelong CDP 9
Hurstville SFP 14
Hurstville LIB 64
Hurstville CDP 13
我可以像这样轻松地将他的逐行转换为 XML:
SELECT(SELECT location, team, score FROM MyTable FOR XML PATH('node'), TYPE ) FOR XML PATH(''), ROOT('root')
产生的 XML 看起来像这样:
<node>
<location>Adelong</location>
<team>SFP</team>
<score>104</score>
</node>
<node>
<location>Adelong</location>
<team>LIB</team>
<score>189</score>
</node>
<node>
<location>Adelong</location>
<team>CDP</team>
<score>9</score>
</node>
但我真正想要的是:
<location name="Adelong">
<node>
<team>SFP</team>
<score>104</score>
</node>
<node>
<team>LIB</team>
<score>189</score>
</node>
<node>
<team>CDP</team>
<score>9</score>
</node>
</location>
您可以使用临时派生的 table 来获取不同的位置,select 从中获取位置并在相关子查询中获取球队和分数。
SELECT t1.location [@name],
(SELECT t2.team,
t2.score
FROM mytable t2
WHERE t2.location = t1.location
FOR XML PATH('node'),
TYPE)
FROM (SELECT DISTINCT
t1.location
FROM mytable t1) t1
FOR XML PATH('location');
这是基于 XQuery FLWOR 表达式的解决方案。
SQL
-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, [location] VARCHAR(20), team CHAR(3), score INT);
INSERT INTO @tbl (location, team, score)
VALUES
('Adelong' ,'SFP', 104)
,('Adelong' ,'LIB', 189)
,('Adelong' ,'CDP', 9 )
,('Hurstville' ,'SFP', 14 )
,('Hurstville' ,'LIB', 64 )
,('Hurstville' ,'CDP', 13 );
-- DDL and sample data population, end
SELECT (
SELECT *
FROM @tbl
FOR XML PATH('r'), TYPE, ROOT('root')).query('<root>
{
for $x in distinct-values(/root/r/location)
return <location name="{$x}">
{
for $y in /root/r[location/text() = $x]
return <node>
{$y/team}
{$y/score}
</node>
}
</location>
}
</root>');
我正在使用 FOR XML 从 SQL 查询中创建一个 XML 文件。我希望元素基于特定列的公共值,在本例中为 "location":
location team score
Adelong SFP 104
Adelong LIB 189
Adelong CDP 9
Hurstville SFP 14
Hurstville LIB 64
Hurstville CDP 13
我可以像这样轻松地将他的逐行转换为 XML:
SELECT(SELECT location, team, score FROM MyTable FOR XML PATH('node'), TYPE ) FOR XML PATH(''), ROOT('root')
产生的 XML 看起来像这样:
<node>
<location>Adelong</location>
<team>SFP</team>
<score>104</score>
</node>
<node>
<location>Adelong</location>
<team>LIB</team>
<score>189</score>
</node>
<node>
<location>Adelong</location>
<team>CDP</team>
<score>9</score>
</node>
但我真正想要的是:
<location name="Adelong">
<node>
<team>SFP</team>
<score>104</score>
</node>
<node>
<team>LIB</team>
<score>189</score>
</node>
<node>
<team>CDP</team>
<score>9</score>
</node>
</location>
您可以使用临时派生的 table 来获取不同的位置,select 从中获取位置并在相关子查询中获取球队和分数。
SELECT t1.location [@name],
(SELECT t2.team,
t2.score
FROM mytable t2
WHERE t2.location = t1.location
FOR XML PATH('node'),
TYPE)
FROM (SELECT DISTINCT
t1.location
FROM mytable t1) t1
FOR XML PATH('location');
这是基于 XQuery FLWOR 表达式的解决方案。
SQL
-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, [location] VARCHAR(20), team CHAR(3), score INT);
INSERT INTO @tbl (location, team, score)
VALUES
('Adelong' ,'SFP', 104)
,('Adelong' ,'LIB', 189)
,('Adelong' ,'CDP', 9 )
,('Hurstville' ,'SFP', 14 )
,('Hurstville' ,'LIB', 64 )
,('Hurstville' ,'CDP', 13 );
-- DDL and sample data population, end
SELECT (
SELECT *
FROM @tbl
FOR XML PATH('r'), TYPE, ROOT('root')).query('<root>
{
for $x in distinct-values(/root/r/location)
return <location name="{$x}">
{
for $y in /root/r[location/text() = $x]
return <node>
{$y/team}
{$y/score}
</node>
}
</location>
}
</root>');