Sql递归查询创建唯一列表

时间:2010-07-01 14:32:53

标签: performance recursion sql

出于速度原因,我需要将一些代码从C#移到存储过程中。我想要获得的是基于CategoryId的RoleTemplates(或CategoryToRoleTemplate)表中的唯一TemplateIds列表。
但是,我需要查询来遍历Category.ParentId关系,并收集所有父项的相关TemplateIds。这需要在ParentId为空之前发生。

理想情况下,结果应该是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是关键。

4 个答案:

答案 0 :(得分:2)

我会建议CTE进行该查询。请记住,虽然树实际上将从null开始直到耗尽。

示例(给出您的代码可以使用或不使用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)

Good Point(tm):不要忘记WITH关键字之前的分号。

答案 1 :(得分:1)

使用递归公用表表达式:

http://msdn.microsoft.com/en-us/library/ms186243.aspx

答案 2 :(得分:1)

请查看此链接http://msdn.microsoft.com/en-us/library/ms186243.aspx

我首先使用带有 语法的表格类别,然后再加入其他表格。

答案 3 :(得分:1)

我现在时间不够,所以我不能具体,但我会查看Common Table Expressions,我过去曾成功使用它来实现递归。