"For xml path" SQL 中没有子查询
"For xml path" without subquery in SQL
是否可以在没有 'select' 子查询的情况下获得与此查询相同的结果?有人对如何解决这个问题有什么建议吗?
select d.Id as '@DishId', d.Name as '@DishName', (
select p.Id as '@ProdId', p.Name as '@PName', s.Quantity as '@Quantity'
from Structure s
inner join Products p on s.ProdId = p.Id where s.DishId = d.Id
for xml path('Product'), type
) as 'Products'
from Dishes d
for xml path('Dish'), root('Dishes')
本次查询的结果
<Dishes>
<Dish DishId="1" DishName="Potato and Meat">
<Products>
<Product ProdId="1" PName="Meat" Quantity="100" />
<Product ProdId="2" PName="Potato" Quantity="150" />
</Products>
</Dish>
<Dish DishId="2" DishName="Tea">
<Products>
<Product ProdId="3" PName="Water" Quantity="10" />
<Product ProdId="4" PName="Tea" Quantity="150" />
<Product ProdId="5" PName="Sugar" Quantity="10" />
</Products>
</Dish>
</Dishes>
生成数据库的脚本
带子查询的方法是正确的首选方法。
这是通过 XQuery 及其 FLWOR 表达式实现预期结果的另一种方法。
这是一个两步过程。
首先,我们将生成以下原始 XML:
<root>
<row Id="1" Name="Potato and Meat" DishId="1" ProdId="1" Quantity="100" PName="Meat" />
<row Id="1" Name="Potato and Meat" DishId="1" ProdId="2" Quantity="150" PName="Potato" />
<row Id="2" Name="Tea" DishId="2" ProdId="3" Quantity="10" PName="Water" />
<row Id="2" Name="Tea" DishId="2" ProdId="4" Quantity="150" PName="Tea" />
<row Id="2" Name="Tea" DishId="2" ProdId="5" Quantity="10" PName="Sugar" />
</root>
第二步是通过使用 FLWOR 表达式调用 .query()
方法来组合最终的 XML。
SQL
SELECT (SELECT d.* , s.*, p.Name AS PName
FROM dbo.Dishes AS d
INNER JOIN dbo.Structure AS s ON d.Id = s.DishId
INNER JOIN dbo.Products AS p ON s.ProdId = p.Id
FOR XML RAW, TYPE, ROOT('root')
).query('<Dishes>
{
for $d in distinct-values(/root/row/@Id)
return <Dish DishId="{$d}" DishName="{(/root/row[@Id=$d]/@Name)[1]}">
<Products>
{
for $p in /root/row[@Id=$d]/@ProdId
return <Product ProdId="{$p}"
PName="{/root/row[@ProdId=$p]/@PName}"
Quantity="{/root/row[@ProdId=$p]/@Quantity}" />
}
</Products>
</Dish>
}
</Dishes>');
是否可以在没有 'select' 子查询的情况下获得与此查询相同的结果?有人对如何解决这个问题有什么建议吗?
select d.Id as '@DishId', d.Name as '@DishName', (
select p.Id as '@ProdId', p.Name as '@PName', s.Quantity as '@Quantity'
from Structure s
inner join Products p on s.ProdId = p.Id where s.DishId = d.Id
for xml path('Product'), type
) as 'Products'
from Dishes d
for xml path('Dish'), root('Dishes')
本次查询的结果
<Dishes>
<Dish DishId="1" DishName="Potato and Meat">
<Products>
<Product ProdId="1" PName="Meat" Quantity="100" />
<Product ProdId="2" PName="Potato" Quantity="150" />
</Products>
</Dish>
<Dish DishId="2" DishName="Tea">
<Products>
<Product ProdId="3" PName="Water" Quantity="10" />
<Product ProdId="4" PName="Tea" Quantity="150" />
<Product ProdId="5" PName="Sugar" Quantity="10" />
</Products>
</Dish>
</Dishes>
生成数据库的脚本
带子查询的方法是正确的首选方法。
这是通过 XQuery 及其 FLWOR 表达式实现预期结果的另一种方法。
这是一个两步过程。
首先,我们将生成以下原始 XML:
<root>
<row Id="1" Name="Potato and Meat" DishId="1" ProdId="1" Quantity="100" PName="Meat" />
<row Id="1" Name="Potato and Meat" DishId="1" ProdId="2" Quantity="150" PName="Potato" />
<row Id="2" Name="Tea" DishId="2" ProdId="3" Quantity="10" PName="Water" />
<row Id="2" Name="Tea" DishId="2" ProdId="4" Quantity="150" PName="Tea" />
<row Id="2" Name="Tea" DishId="2" ProdId="5" Quantity="10" PName="Sugar" />
</root>
第二步是通过使用 FLWOR 表达式调用 .query()
方法来组合最终的 XML。
SQL
SELECT (SELECT d.* , s.*, p.Name AS PName
FROM dbo.Dishes AS d
INNER JOIN dbo.Structure AS s ON d.Id = s.DishId
INNER JOIN dbo.Products AS p ON s.ProdId = p.Id
FOR XML RAW, TYPE, ROOT('root')
).query('<Dishes>
{
for $d in distinct-values(/root/row/@Id)
return <Dish DishId="{$d}" DishName="{(/root/row[@Id=$d]/@Name)[1]}">
<Products>
{
for $p in /root/row[@Id=$d]/@ProdId
return <Product ProdId="{$p}"
PName="{/root/row[@ProdId=$p]/@PName}"
Quantity="{/root/row[@ProdId=$p]/@Quantity}" />
}
</Products>
</Dish>
}
</Dishes>');