2011-12-23 54 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

相關問題