再帰

2011-12-23 15 views
1

でSQLのすべての先祖と子孫の行を取得するにはどうすれば持って再帰

table data and schema

と、問題は、私はのデータを取得したいということであるMS SQLサーバーのテーブル名のカテゴリで、次の表のデータ祖父母、親、兄弟、児童、児童、および自己。

私の要点を得ることができたら幸いです。私の質問から私の要求を編集することができます。

これまでのところ、私はstackoverflowを検索しましたが、親を使って完全な階層データを取得する例がたくさんありましたが、子を渡して子、子、自己を取得することはありません。

linqを使用してソリューションを提供するソリューションも公開されています。カテゴリで完全なデータを取得でき、linq on .csページを使用できるためです。

編集: 私はheritageCategoryIdある7を渡す場合、クエリは、私はそれを行う方法がある次の行

desired result in case category id 7 pass

答えて

2

回答は、却下的な「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

+0

私は理解しません - これは、各レベルが識別されたテーブル全体を返します。どうしたの? –

+0

yah私は以前のコメントを残念に思ったレベルについて忘れてしまった今、私はこのテーブルに私の望む結果を問い合わせる必要がある – rahularyansharma

0

を返す関数を作成し、それを持っている必要がありますあなたがデータを出力しようとしている場合、プログラムのあらゆるレベルで自分自身を呼び出すか、各レベルを書き出すか、アセンブリにパブリックスコープの静的varible/singleton配列の配列を持たせます。

それほどはっきりしない反復はめったにありません。

+1

私が探していますSQLのいくつかの並べ替え – rahularyansharma

+0

私はストアドプロシージャとしてそれを行うことができるかもしれないと思う?再帰を処理するためにストアドプロシージャを呼び出してください。 –