2011-12-23 56 views
1

我有在MS SQL Server表的名称分类如下表数据如何让SQL中的所有祖先和后代行递归

table data and schema

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

我希望你能明白我的观点,如果需要我的要求有任何更多的澄清,我可以编辑我的问题,只是在下面发表评论。

至于我的尝试我搜索stackoverflow和我发现了很多例子,使用父母得到完整的分层数据,但没有找到任何有关传递孩子,并得到父母,子孩子和自我。

我也开放了解决方案,它使用linq为我提供解决方案,因为那样我就可以在类别中获取完整数据,并且可以使用linq他们的.cs页面。

编辑: 如果我通过了7这是heritageCategoryId然后查询应返回以下行

desired result in case category id 7 pass

回答

2

答案是使用recusive“Common Table Expression”或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 
+0

它将只返回子女,子女,但我想父母,兄弟姐妹也 – rahularyansharma 2011-12-23 05:09:24

+0

我不明白 - 这返回整个表,每个级别确定。有什么问题? – 2011-12-23 05:24:30

+0

我现在检查它对不起之前的评论我忘了关于水平现在我不得不查询这张表为我想要的结果 – rahularyansharma 2011-12-23 05:27:31

0

我做的是,创造一个功能,有它的方式为程序的每个级别调用自己,如果你试图输出数据ud写出每个级别,或者让它在公共范围内汇编某种数组,或者静态变量/单例。

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

+1

我找一些类型的sql在sql – rahularyansharma 2011-12-23 05:00:14

+0

即时通讯思维你可能能够做到这一点的存储过程?并继续从自身调用存储过程来处理递归。 – 2012-01-04 22:43:40

相关问题