编辑:我之前离得很近。添加了功能示例的小提琴
Edit2:更新小提琴以获得更清洁的程序并更改代码以反映正确的解决方案
这个问题需要一个递归过程来深入挖掘后代树的未知深度。这有可能是一个非常昂贵的操作,并且如果两个类别相互引用为父级,那么这里设计的也可能导致无限循环,因此您可能需要加入一些保护措施来防止这种情况发生。
我使用一个临时表来收集所有不同查询的结果,然后将它们与调用递归过程的过程一起返回,因此只需调用 spAllProductsUnderCateg 即可返回结果集。
CREATE PROCEDURE [spAllProductsUnderCateg]
@categId int
AS
BEGIN
CREATE TABLE #ProductsByCategory (Name varchar(100))
-- This may be completely wrong
INSERT INTO #ProductsByCategory
SELECT DISTINCT p.Name FROM Products p
JOIN Products_Categories pc ON pc.ProductId = p.Id
WHERE pc.CategoryId = @categId
EXEC spGetChildCategories @categId
SELECT DISTINCT * FROM #ProductsByCategory
END
GO
CREATE PROCEDURE [spGetChildCategories]
@categId int
AS
BEGIN
DECLARE @nextCatId int
DECLARE cur CURSOR LOCAL
FOR SELECT DISTINCT Id FROM Categories
WHERE ParentCategoryId = @categId
OPEN cur
FETCH NEXT FROM cur INTO @nextCatId
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO #ProductsByCategory
SELECT DISTINCT p.Name FROM Products p
JOIN Products_Categories pc ON pc.ProductId = p.Id
WHERE pc.CategoryId = @nextCatId
EXEC spGetChildCategories @nextCatId
FETCH NEXT FROM cur INTO @nextCatId
END
CLOSE cur
END
GO
我在 PL/SQL 方面比 T-SQL 更有经验,但这在小提琴中起作用。由于它使用递归、游标和一个额外的表,您肯定会想要评估它的性能限制,但它确实适用于我提供的数据。
这是小提琴