Sql 选择类别及其子体中的项的存储过程
我有这三张桌子Sql 选择类别及其子体中的项的存储过程,sql,sql-server,stored-procedures,Sql,Sql Server,Stored Procedures,我有这三张桌子 Products (Id, Name) Products_Categories (ProductId, CategoryId) Categories (Id, ParentCategoryId) 如你所见 产品到类别是多对多 类别可能有父类,也可能没有父类(父类也是类别) 如何创建一个存储过程来选择类别(包括其子类)下的所有(不同的)产品 我想要的伪代码示例(不是LINQ): Category c; return c.GetSelfAndDescendants().Sele
Products (Id, Name)
Products_Categories (ProductId, CategoryId)
Categories (Id, ParentCategoryId)
如你所见
到产品
是多对多类别
可能有父类,也可能没有父类(父类也是类别)类别
Category c;
return c.GetSelfAndDescendants().Select(x => x.Products).Distinct();
我需要的是存储过程,例如
CREATE PROCEDURE [spAllProductsUnderCateg]
@categId int
AS
BEGIN
SET NOCOUNT ON;
-- This may be completely wrong
SELECT DISTINCT * FROM Products p
JOIN Products_Categories ON Products_Categories.ProductId = p.Id
WHERE...???
END
GO
Edit:我以前根本就不了解。添加了功能示例小提琴 Edit2:更新fiddle以获得更清晰的过程,并更改代码以反映正确的解决方案 这个问题需要一个递归过程来深入挖掘后代树的未知深度。这可能是一个非常昂贵的操作,如果两个类别将彼此称为父类,那么这里设计的操作也可能导致无限循环,因此您可能需要针对这一情况提供一些保护 我使用一个临时表来收集所有不同查询的结果,然后用调用递归过程的过程返回结果,所以只需要调用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方面更有经验,但这是非常有效的。由于它使用递归、游标和一个额外的表,您肯定会想评估它的性能限制,但它确实可以处理我提供给它的数据
你好,谢谢,但事情并没有那么简单。我还需要包括该类别的子类别中的所有产品。这就是我遇到的问题。多个子代级别将需要一个递归过程,该过程将调用自身来检索每个级别的子代。我得准备一把小提琴才能把它弄到手。我看看我能做什么。我很抱歉误解了您的要求。添加了一个功能示例链接到小提琴。哇,非常感谢小提琴!我想如果你把相关的代码粘贴到stackoverflow上也会很好。不客气。我在这里更新了代码,并稍微调整了小提琴,因此该过程直接使用临时表返回结果。