2016-12-15 6 views
0

ノードのテーブル(Idとその親Id)があれば、どのようにしてルートノード、インナーノード、リーフノードをすべて取得できますか?ここでルートノード、内部ノード、およびリーフノードをテーブルから取得しますか?

は、私がこれまで持っているものです。

ルートノード

SELECT Id, "Root" FROM NodeTable 
WHERE ParentId IS NULL; 

インナーノード

??? 

リーフノードは

SELECT N1.Id, "Leaf" FROM NodeTable N1 
LEFT JOIN NodeTable N2 ON N1.Id = N2.ParentId 
WHERE N2.ParentId IS NULL; 

はこの正しいですか? 1つのクエリでこれを実行できる方法はありますか?

答えて

3

「内部ノード」クエリは、「リーフノード」クエリと同様に導出できます。

SELECT DISTINCT N1.Id, "Inner" 
FROM NodeTable N1 
JOIN NodeTable N2 
    ON N2.ParentId = N1.ID 
WHERE N1.ParentId IS NOT NULL; 

これは、あなた(彼らはnull以外ParentIdはを持っているので)ルートノードではないノード(N1)の全てを取得し、子供(N2)を持っているでしょう。

はい、これをすべて1つのクエリで並べ替えるには、UNIONキーワードを使用します。

SELECT Id, "Root" 
FROM NodeTable 
WHERE ParentId IS NULL 
UNION 
SELECT DISTINCT N1.Id, "Inner" 
FROM NodeTable N1 
JOIN NodeTable N2 
    ON N2.ParentId = N1.ID 
WHERE N1.ParentId IS NOT NULL 
UNION 
SELECT N1.Id, "Leaf" 
FROM NodeTable N1 
LEFT JOIN NodeTable N2 
    ON N1.Id = N2.ParentId 
WHERE N2.ParentId IS NULL; 
+0

素晴らしい、ありがとうございました!何らかの理由で、私はあなた自身の内部クエリを実行するとき、すべてのノードが2回現れます。私はMySQLにはまだまだ慣れていませんが、それがなぜ、どうやって解決できるのか理解できますか? –

+0

実際、この問題はUnionキーワードを使用したときに消えました。奇妙な! –

+1

@IanMobbs Unionは集合演算子です。したがって、行が2回クエリされた後、何かと結合された場合、その行は1回だけ表示されます。 – nasukkin

2
select case 
     when p is null then concat(n, ' Root') 
     when n in (select distinct p from bst) then concat(n, ' Inner') 
     else concat(n, ' Leaf') 
    end 
from bst 
order by n asc 
+2

あなたはこの答えを詳しく説明したいかもしれません。元のコードに何が間違っていたか、どのように変更したのかを示します。これにより、将来の訪問者にとってより便利になります。 – miken32

関連する問題