2017-11-09 9 views
0

を接合することで、単一のテーブルに連結を使用して選択し、私は3列で一つのテーブルを持っているが親&子供のidの

+---------------------------------------+ 
| id | name    | parent_id | 
+---------------------------------------+ 
| -1 |/     |   | 
| 1 | Organization  | -1  | 
| 2 | United States  | 1  | 
| 3 | Business Analyst | 1  | 
| 4 | Human Resources  | 1  | 
| 5 | Benefits Manager | 4  | 
| 6 | Metropolitan Plant | 2  | 
| 7 | Administration  | 6  | 
+---------------------------------------+ 

以下であると、私のクエリは、私は以下のように出力を期待しています。この

SELECT CONCAT(parent.name, '/', child.name) AS path 
FROM table_name AS child INNER JOIN table_name AS parent 
ON child.id = parent.parent_id 

のようなものです。

/Organization 
/Organization/United States 
/Organization/Business Analyst 
/Organization/Human Resources 
/Organization/Human Resources/Benefits Manager 
/Organization/United States/Metropolitan Plant 
/Organization/United States/Metropolitan Plant/Administration 
+0

正しくタグ付けしてください。これはMySQLかPosgresですか?あなたは両方のタグを付けます。両方にすることはできません。 – Eric

答えて

0

[OK]を...特にループを行う使用して...これを行うには、よりエレガントな方法があるかもしれない...しかし、すぐに頭に浮かぶものと、あなたがする必要があるかもしれないいくつかが加わります。最大レベルは低いですか?そうだといい。ここでアイデアですが、それは厄介だし、あなたのデータサイズに応じてスプールの多くを必要とするかもしれない:

SELECT CONCAT(path2, '/', D.name) AS path3 
FROM 
(SELECT CONCAT(path1, '/', B.name) AS path2 
FROM 
(SELECT CONCAT(parent.name, '/', child.name) AS path1 
FROM table_name AS parent LEFT JOIN table_name AS child 
ON child.id = parent.parent_id) AS A 
LEFT JOIN TABLE_NAME AS B 
ON A.id = B.parent_id) AS C 
LEFT JOIN TABLE_NAME AS D 
ON C.id = D.parent_id 

上記のコードは唯一の3つのレベルにそれを取るでしょう。何か良いことがあれば投稿します。

0

はあなたが非常に近いことでしょうそれ

ここ

WITH foo (id, parent_id, name, fullpath) 
    AS (SELECT id, 
       parent_id, 
       name, 
       '/' AS fullpath 
      FROM table_name 
      WHERE parent_id IS NULL 
     UNION ALL 
     SELECT m.id, 
       m.parent_id, 
       m.name, 
       f.fullpath || m.name || '/' AS fullpath 
      FROM foo f JOIN table_name m ON (m.parent_id = f.id)) 
SELECT fullpath FROM foo 
WHERE id > 0 
を階層的なクエリを使用すると期待していると思います。

関連する問題