如何使用递归获取sql中的所有优先级和后代行

时间:2011-12-23 04:49:46

标签: sql sql-server-2005 linq-to-sql recursion

我在ms sql server表名类别中有以下表数据

table data and schema

问题是我想获得祖父母,父母,兄弟姐妹,子女和子女以及自我的数据。

我希望你明白我的意思,如果我需要更多的澄清,我可以编辑我的问题,只需在下面发表评论。

到目前为止,我搜索了stackoverflow,我发现了许多使用父级获取完整分层数据的例子,但没有发现任何与传递子项并获得父,子子和自我相关的内容。

我也对使用linq为我提供解决方案的解决方案持开放态度,因为我可以在类别中获取完整数据,并且可以在.cs页面上使用linq。

编辑: 如果我通过7 heritage CategoryId,则查询应返回以下行

desired result in case category id 7 pass

2 个答案:

答案 0 :(得分:2)

答案是使用隐性“公用表表达式”或CTE。这允许您构建层次结构。以下是根据此页面修改以匹配您的结构的示例:http://msdn.microsoft.com/en-us/library/ms186243.aspx

WITH CategoryStructured (ParentCategoryID, CategoryID, Description, Status, Level) 
AS 
( 
-- Anchor member definition 
SELECT c.ParentCategoryID, c.CategoryID, c.Description, c.Status, 
0 AS Level 
FROM Category AS c 
WHERE c.ParentCategoryID=0 
UNION ALL 
-- Recursive member definition 
SELECT c.ParentCategoryID, c.CategoryID, c.Description, c.Status, 
Level + 1 
FROM Category AS c 

INNER JOIN CategoryStructured AS c_parent 
ON c.ParentCategoryID = c_parent.CategoryID 
) 
-- Statement that executes the CTE 
SELECT distinct cs.ParentCategoryID, cs.CategoryID, cs.Description, cs.Status, cs.Level 
FROM 
CategoryStructured cs, 


(SELECT level,ParentCategoryID,CategoryID from CategoryStructured WHERE (categoryID = 4) OR (level = 1 AND parentCategoryID = 4)) as thisCategory 


WHERE cs.level BETWEEN thisCategory.level - 1 AND thisCategory.level+1 
AND ((thisCategory.level != 0 AND cs.ParentCategoryID = thisCategory.ParentCategoryID) 
OR cs.categoryID = thisCategory.ParentCategoryID 
OR cs.ParentCategoryID = thisCategory.CategoryID 
OR cs.CategoryID = thisCategory.CategoryID)

已更新,以反映您更新的问题。

编辑我知道你能够让上面的内容基本上为你增添了明显的功能,但在离开聊天后我想到了一个更好的方法来解决这个问题:

WITH CategoryStructured (ParentCategoryID, CategoryID, Description, Status, Level)
AS
(
-- Anchor member definition
    SELECT c.ParentCategoryID, c.CategoryID, c.Description, c.Status, 
        0 AS Level
    FROM Categories AS c
    WHERE 
     (c.ParentCategoryID IS NULL AND c.categoryID = 7) -- when 7 is a top level category, then it is the root level
     OR (c.categoryID = (SELECT c2.parentCategoryID FROM Categories c2 WHERE c2.categoryID = 7)) -- when 7 is some non-top level category, then 7's parent is the root
    UNION ALL
-- Recursive member definition
    SELECT c.ParentCategoryID, c.CategoryID, c.Description, c.Status, 
        Level + 1
    FROM Categories AS c

    INNER JOIN CategoryStructured AS c_parent
        ON c.ParentCategoryID = c_parent.CategoryID
)
-- Statement that executes the CTE
SELECT cs.ParentCategoryID, cs.CategoryID, cs.Description, cs.Status, cs.Level
FROM 
  CategoryStructured cs
WHERE cs.level < 3
ORDER BY cs.level

答案 1 :(得分:0)

我这样做的方法是,创建一个函数并让它为程序的每个级别调用自己,如果你试图输出数据ud写出每个级别,或者让它在公共范围内组装某种数组,或静态变量/单例。

它不漂亮,但很少有递归。