Я видел несколько сообщений о похожих проблемах, но решения для меня не работают, так как я не хочу показывать родителей среднего звена детьми. Я вполне уверен, что 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
Запрос, который я пробовал, немного сложнее, чем примеры, которые я видел, потому что мне нужно объединить несколько таблиц, чтобы все заработало. Я должен объединить идентификаторы базы данных с именами, et c. Я также не видел, чтобы кто-то спрашивал только о потомках нижнего уровня, подобных этому.
Я имею дело с базой данных рецептов, поэтому эти "родители" - это рецепты, а "дети" - предметы инвентаря. Но предмет инвентаря может быть суб-рецептом; состоит из других предметов инвентаря и, возможно, даже других суб-рецептов. Вот где возникает этот произвольный уровень глубины. Я пытаюсь написать запрос типа «список покупок», поэтому для каждого существующего рецепта (рецепт или подрецепт) я бы хотел перечислить все его предметы инвентаря нижнего уровня (то есть никакие подрецепты, только их отдельные компоненты). К счастью, в одной из моих таблиц есть столбец с битом, указывающим статус ингредиента как подрецепт.
Вот то, с чем я работаю до сих пор, но это не дает желаемого результата:
Таблица RecpInv
('rInv') связывает родителей с детьми (идентификатор элемента с идентификатором рецепта)
Таблица Inv
('inv') связывает идентификатор элемента с именем элемента
Таблица Recipe
('recipes') связывает идентификатор рецепта с именем рецепта
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
Это правильные ингредиенты верхнего уровня слева для рецептов справа. Предметы, начинающиеся с заглавной буквы в левом столбце, являются субрецептами и состоят из инвентарных предметов и / или субрецептов. Я не хочу никаких рецептов слева. Просто их компоненты нижнего уровня. Таким образом, в айоли, жареном чесноке c, не должно быть пюре из жареного чеснока c в качестве одного из ингредиентов. Вместо этого должны быть включены компоненты нижнего уровня для 'Roasted Garli c Puree'. То же самое касается «Гарли c, фарш».
Я понимаю, что это довольно большая просьба, но любая помощь приветствуется.