我有一个非常简单的SQL Server表,我想找到每个食谱的成本。每个食谱都有一份食材清单。食谱也可能有子食谱。
最简单的RecipeId-1鸡肉三明治示例,其成分低于:
由于蒜酱RecipeId-2也是配方(用作上面的子配方),它有以下成分:
最后我的表结构:
现在我想要一个能让我获得鸡肉三明治费用的视图 选择*来自RecursiveRecipeView其中RecipeId = 1,结果将是:$ 8(1 + 5 + 1.5 + .5)。
我试过下面的查询,但是我收到错误“在递归公用表表达式'Tree'的递归部分中不允许使用GROUP BY,HAVING或聚合函数”
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
请注意,有些食谱甚至可以达到10级。有人可以帮我吗?
答案 0 :(得分:2)
首先,您的CTE出现了一些问题。它将无限地递归,这是不好的。我在您的TREE
和PARENT
个对象之间翻转了您的联接。
其次,正如已经指出的那样,您需要将聚合从CTE中拉出来。只需让您的CTE选择您的详细信息,然后在最终查询中总结。这里有一个问题是你需要在CTE的顶层指定一个特定的RecipeID,这样你才真正拥有“顶级”水平。
SQLFiddle(我添加了第三级,只是为了测试它)。
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