【发布时间】:2023-12-11 11:33:01
【问题描述】:
我看过一些类似问题的帖子,但解决方案对我不起作用,因为我不想让中层父母像孩子一样。我相当肯定Recursive Common Table Expressions 会成功。
基本上,我有一个列出所有父子关系的表,但它只有 1 级深。我想查询此表,以便对于所有父项,返回所有底层后代,以获得任意深度。例如:
What the table looks like what I'd like my query to return
child | parent child | parent
-------------- --------------
a1 | b1 a2 | b1
a2 | b1 a3 | b1
a3 | b1 c1 | b1
c1 | a1 c2 | b1
c2 | a1 c1 | a1
c2 | a1
我一直在尝试的查询比我看到的示例要复杂一些,因为我必须连接多个表才能使事情顺利进行。我必须将数据库 ID 与名称等连接起来。我还没有看到有人像这样只要求底层后代。
我正在处理一个食谱数据库,所以这些“父母”是食谱,而“孩子”是库存物品。但是库存项目可能是子配方;由其他库存项目甚至可能其他子配方组成。这就是这种任意深度的来源。我试图编写的查询是一个“购物清单”——所以对于每个存在的食谱(食谱或子食谱),我想列出所有它的底层库存项目(即没有子配方,只有它们的单个组件)。幸运的是,我的一张表有一个列,其中显示了一种成分作为子配方的状态。
这是我目前正在使用的,但没有给出预期的结果:
表 RecpInv ('rInv') 将父母与孩子相关联(项目 ID 与食谱 ID)
表 Inv ('inv') 将项目 ID 与项目名称相关联
表 Recipe ('recipes') 将配方 ID 与配方名称相关联
WITH ingredients AS(
SELECT
inv.ItemName AS 'Inventory Item',
recipes.RecipeName AS 'Recipe',
rInv.RecipeID AS 'Recipe ID',
rInv.ItemID AS 'Item ID'
FROM [DataDir].[dbo].[RecpInv] AS rInv
INNER JOIN [DataDir].[dbo].[Inv] AS inv
ON inv.ItemID = rInv.ItemID
INNER JOIN [DataDir].[dbo].[Recipe] AS recipes
ON recipes.RecipeID = rInv.RecipeID
WHERE recipes.ProfCentID = @profitCenter
AND inv.ProfCentID = @profitCenter
UNION ALL
SELECT
inv2.ItemName AS 'Inventory Item',
recipes2.RecipeName AS 'Recipe',
rInv2.RecipeID AS 'Recipe ID',
rInv2.ItemID AS 'Item ID'
FROM [DataDir].[dbo].[RecpInv] AS rInv2
INNER JOIN [DataDir].[dbo].[Recipe] AS recipes2
ON rInv2.RecipeID = recipes2.RecipeID
INNER JOIN [DataDir].[dbo].[Inv] AS inv2
ON rInv2.ItemID = inv2.ItemID
INNER JOIN ingredients
ON rInv2.ItemID = ingredients.[Recipe ID]
WHERE recipes2.ProfCentID = @profitCenter
AND inv2.ProfCentID = @profitCenter
AND inv2.SubRecipe = 0
)
SELECT
ingredients.[Inventory Item],
ingredients.[Recipe]
FROM ingredients
ORDER BY ingredients.[Recipe]
以下是部分查询结果。我从这个查询中得到了 32,000 行:
mayonnaise, vegan Aioli, Roasted Garlic
Roasted Garlic Puree Aioli, Roasted Garlic
salt, kosher Aioli, Roasted Garlic
juice, lemon Aioli, Roasted Garlic
mayonnaise, canola Aioli, Truffle
spice, black truffle rub Aioli, Truffle
pepper, black ground Aioli, Truffle
mustard, stoneground Aioli, Truffle
Garlic, Minced Aioli, Truffle
这些是左侧食谱的正确*成分。左栏中以大写字母开头的项目是子配方,由库存项目和/或子配方组成。我不想要左边的任何子食谱。只是他们的底层组件。因此,“蒜泥蛋黄酱,烤大蒜”不应该将“烤大蒜泥”作为其成分之一。应该包括“烤大蒜泥”的底层组件。 '大蒜,剁碎'也是如此。
我知道这是一个很大的问题,但我们非常感谢任何帮助。
【问题讨论】:
-
请包含上述查询@DavidMichael的当前结果?
-
@Birel 我在帖子中添加了一些结果。不确定它们是否会有所帮助...
标签: sql-server tsql recursion recursive-cte