"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>

生成数据库的脚本

https://pastebin.com/V5MkBGQq

带子查询的方法是正确的首选方法。

这是通过 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>');