2012-05-07 1 views
1

私は以下のようなテーブルを持っている場合: -自己参照表の各カテゴリの最上位親を取得するための再帰的LinqまたはSqlクエリ

create table Categories(CategoryId int primary key, 
ParentCategoryId int foreign key references Categories(CategoryId)) 

例えば、私は私のテーブルに次のデータを持っている場合: - 任意の助け

CategoryID ParentCategoryId 
1   2 
2   3 
3   4 
4   NULL 
5   6 
6   7 
7   NULL 
8   9 
9   NULL 

Result:  

CategoryId ParentCategoryId 
1   4 
2   4 
3   4 
4   NULL 
5   7 
6   7 
7   NULL 
8   9 
9   NULL 

ありがとう!

+0

ルートカテゴリのParentCategoryIdは(NULL、独自のカテゴリID、その他のもの)に設定されていますか? – JamieSee

+0

質問が更新されました。 – teenup

答えて

1

ここでは、再帰CTEソリューションです。おそらくよりエレガントで効率的でしょうか?

WITH TopLevelParents AS (
    SELECT CategoryID, ParentCategoryID 
    FROM Categories 
    WHERE ParentCategoryID IS NULL 
    UNION ALL 
    SELECT c.CategoryID, ISNULL(p.ParentCategoryID, p.CategoryID) ParentCategoryID 
    FROM Categories c 
    JOIN TopLevelParents p ON c.ParentCategoryID = p.CategoryID 
) 
SELECT * 
FROM TopLevelParents 
ORDER BY 1 
1

SQLでは、このようにそれを行うことができます。

DECLARE @childId int 
SET @childId = 1 

DECLARE @nextId int 
DECLARE @currentId int 

SET @nextId = @childId 

WHILE (NOT (@nextId IS NULL)) 
BEGIN 
    SET @currentId = @nextId 

    SELECT @nextId = ParentCategoryId 
    FROM Categories 
    WHERE CategoryId = @currentId 
END 

SELECT @currentId AS RootCategoryId 

は、LINQのでは、あなたのようなものを見ている:

public int GetRootCategoryId(int childId) 
{ 
    int? nextId = childId 
    int? currentID; 

    while (nextID != null) 
    { 
     currentID = nextID; 
     nextID = (from category in db.Categories 
       where category.CategoryId = currentID 
       select category.ParentCategoryId).First(); 
    } 

    return currentID; 
} 
+0

Hmmm ...これは、一度に1つしか実行しません。テーブル全体を最初に示唆したければ、SQLでは非効率的かもしれません。それでも、より汎用的な用途のための良いアプローチです。 – user12861

1
CREATE TABLE #Parents (CategoryID INT PRIMARY KEY, ParentCategoryID INT) 
INSERT #Parents 
SELECT * 
FROM Categories 
WHILE @@ROWCOUNT != 0 BEGIN 
    UPDATE p 
    SET p.ParentCategoryID = c.ParentCategoryID 
    FROM #Parents p 
    JOIN Categories c ON p.ParentCategoryID = c.CategoryID 
    WHERE c.ParentCategoryID IS NOT NULL 
END 
SELECT * 
FROM #Parents 
ORDER BY 1 
DROP TABLE #Parents 
関連する問題