2010-07-01 134 views
1

爲了速度的原因,我需要將一些代碼從C#移動到一個存儲過程。我想要得到的是基於CategoryId的RoleTemplates(或者CategoryToRoleTemplate)表格中的TemplateIds的唯一列表。
但是,我需要查詢漫步Category.ParentId關係,並收集所有父級的相關TemplateIds。這需要發生,直到ParentId爲空。Sql遞歸查詢來創建一個唯一的列表

理想情況下,結果應該是RoleTemplate.TemplateIds的唯一列表。

表結構...

Categories 
------------------------------ 
CategoryId uniqueidentifier 
ParentId  uniqueidentifier <-- Relationship to Categories.CategoryId. 
Name   varchar (50) 

CategoryToRoleTemplate 
------------------------------ 
CategoryId uniqueidentifier <-- Relationship to Categories.CategoryId. 
TemplateId uniqueidentifier <-- Relationship to RoleTemplates.TemplateId. 

RoleTemplates 
------------------------------ 
TemplateId uniqueidentifier 
Name   varchar (50) 

我使用SQL Server 2008 R2。

謝謝!

編輯:

最終的解決方案:

with CategoryHierarchy (ParentId) 
as (
    -- Anchor member definition 
    select CategoryId from Categories 
    where CategoryId = @id 
    union all 

    -- Recursive member definition 
    (select c.ParentId from Categories as c 
     inner join CategoryHierarchy as p 
     on c.CategoryId = p.ParentId) 
) 

select distinct TemplateId from CategoryToRoleTemplates where CategoryId in (select CategoryId from CategoryHierarchy); 

感謝所有誰回答! CTE是關鍵。

回答

2

我會建議CTE做這個查詢。請記住,樹實際上會從零開始,直到耗盡。

實例(可能會或可能無法正常工作OOB給您的代碼):

; WITH CategoryTree(CategoryID, sorthelp) AS 
(SELECT CategoryID, 0 FROM Categories WHERE ParentID IS NULL) 

UNION ALL 

(SELECT C.CategoryID, CT.sorthelp + 1 FROM Categories C INNER JOIN CategoryTree CT ON C.PARENTID = CT.CategoryID) 

SELECT DISTINCT TemplateID FROM RoleTemplates WHERE CategoryID IN (SELECT CategoryID FROM CategoryTree) 

好點(Tm):不要忘記之前WITH關鍵字分號。

1

我現在時間很短,所以我不能具體說明,但是我會查看公用表表達式,過去我成功地用它來實現遞歸。