Sql server 递归部分中不允许使用sql视图错误组BY、HAVING或aggregate函数中的递归计算

Sql server 递归部分中不允许使用sql视图错误组BY、HAVING或aggregate函数中的递归计算,sql-server,recursion,Sql Server,Recursion,我有一个非常简单的SQL Server表,我想找出每个配方的成本。每个食谱都有一份配料表。配方也可能有子配方 RecipeId-1鸡肉三明治的最简单示例,包含以下成分: IngreditID-1面包(一种配料)-价格为1美元 IngreditID-2炸鸡(一种配料)-价格为5美元 RecipeId-2大蒜酱(一个副配方)-价格为2美元 由于大蒜酱RecipeId-2也是一个配方(用作上面的子配方),它有以下成分: IngredientId-3生大蒜-价格1.5美元 IngredientId-4水

我有一个非常简单的SQL Server表,我想找出每个配方的成本。每个食谱都有一份配料表。配方也可能有子配方

RecipeId-1鸡肉三明治的最简单示例,包含以下成分:

  • IngreditID-1面包(一种配料)-价格为1美元
  • IngreditID-2炸鸡(一种配料)-价格为5美元
  • RecipeId-2大蒜酱(一个副配方)-价格为2美元
  • 由于大蒜酱RecipeId-2也是一个配方(用作上面的子配方),它有以下成分:

  • IngredientId-3生大蒜-价格1.5美元
  • IngredientId-4水-成本为0.5美元
  • 最后,我的表结构:

    现在我想要一个能给我鸡肉三明治价格的视图,比如 从RecursiveRecipeView中选择*,其中RecipeId=1,结果为:$8(1+5+1.5+0.5)

    我尝试了下面的查询,但得到错误“在递归公共表表达式“树”的递归部分不允许使用GROUP BY、HAVING或AGGRATE函数”


    请注意,有些食谱甚至有10层深。有人能帮我一下吗?

    首先,你的CTE有些问题。它将无限循环,这是不好的。我在
    父对象
    之间翻转了您的联接

    其次,正如已经指出的,您需要从CTE中提取聚合。只需让您的CTE选择您的详细信息,然后在最终查询中对其进行汇总。这里的一个问题是,您需要在CTE的顶级中指定一个特定的RecipeID,这样您实际上就有了一个“顶级”级别

    (我添加了第三个级别和一个测试)


    谢谢,我会查一下的。顺便问一下,你为什么把recipeid=1放在哪里。若你们把recipeid=1放在那个里,我永远也找不到recipeid的成本2为什么你们把recipeid=1放在那个里。如果你把recipeid=1放在哪里,我将永远无法找到recipeid 2的成本
    where recipe=1
    子句是为了确保你的CTE顶部只有一个实际级别。否则,您将获得表中深度为0的每一行,然后开始处理子级。
    WITH Tree (RecipeId, Depth, SubRecipeId, Cost) AS (
    SELECT RecipeId, 0 AS Depth, RecipeId AS SubRecipeId, SUM(Cost) AS [Cost] FROM RecipeIngredients
    GROUP BY RecipeId
    UNION ALL
    SELECT RI.RecipeId, Parent.Depth + 1 AS Depth,
    CONVERT(varchar(255), Parent.SubRecipeId) AS SubRecipeId, Parent.Cost + cast(sum(RI.cost) as float) AS [Cost] 
    FROM RecipeIngredients RI
    INNER JOIN Tree as Parent ON Parent.RecipeId = RI.SubRecipeId )SELECT distinct RecipeId, Depth, SubrecipeId, Cost FROM Tree
    
    WITH Tree (RecipeId, Depth, SubRecipeId, Cost) AS (
    SELECT RecipeId, 
      0 AS Depth, 
      SubRecipeId, 
      Cost 
    FROM RecipeIngredients 
      where recipeid = 1
    UNION ALL
    SELECT 
      parent.RecipeId, 
      Parent.Depth + 1 AS Depth,
      ri.SubRecipeId AS SubRecipeId, 
      RI.cost as cost
    FROM RecipeIngredients  RI
    INNER JOIN Tree as Parent 
      ON Parent.subrecipeid = RI.recipeid 
    )
    
    SELECT * FROM Tree
    --select sum(cost) from Tree