我看到过一些类似问题的帖子,但是这些解决方案对我不起作用,因为我不想让中级父母作为孩子。我相当确定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
(“配方”)将配方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
这些是左侧食谱中正确的顶级配料。左栏中以大写字母开头的项目是子食谱,并且由库存项目和/或子食谱组成。我不希望在左边有任何子食谱。只是他们的底层组件。因此,“蒜泥蛋黄酱,烤大蒜”不应作为成分之一。应该包括“烤蒜泥”的底层成分。 “大蒜,切碎”也是如此。
我意识到这是一个很大的问题,但是可以提供任何帮助。
答案 0 :(得分:0)
不确定这是否是最有效或雄辩的方法,但它给出了我一直在寻找的结果:
WITH ingredients AS
(
SELECT
inv.ItemName AS 'Inventory Item',
recipes.RecipeName AS 'Recipe',
rInv.RecipeID AS 'Recipe ID',
rInv.ItemID AS 'Item ID',
inv.SubRecipe AS 'Sub'
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',
ingredients.[Recipe] AS 'Recipe',
ingredients.[Recipe ID] AS 'Recipe ID',
inv2.ItemID AS 'Item ID',
inv2.SubRecipe AS 'Sub'
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.RecipeID = ingredients.[Item ID]
WHERE recipes2.ProfCentID = @profitCenter
AND inv2.ProfCentID = @profitCenter
)
SELECT DISTINCT
ingredients.[Inventory Item],
ingredients.[Recipe]
FROM ingredients
WHERE ingredients.[Sub] = 0
ORDER BY ingredients.[Recipe], ingredients.[Inventory Item]