2017-03-13 4 views
0

私は多対多の関係を持っています。 たとえば、1つのメインの親は複数の子を持つことができ、それらの子は複数の親を持つことができます。PostgreSQLでツリーを取得

私のメインテーブルには、今、私はすべての直接の親、兄弟と、指定したエントリの直接の子を取得したい

| childId | parentId | 
---------------------- 
    2  | 1 
    3  | 1 
    4  | 2 
    5  | 2 
    5  | 3 
    6  | 5 

のように見えます

| id | name   | depth | 
--------------------------------- 
1 | top parent  | 0 
2 | child1 of 1 | 1 
3 | child2 of 1 | 1 
4 | child1 of 2 | 2 
5 | child2 of 2/3 | 2 
6 | child1 of 5 | 3 

そして、リンクされたテーブルです。たとえばid 5の場合、2,3,4、および6を取得したいと思います。私はPostgreSQLで初めてです。 1つのクエリでどのように行うことができますか?結果を名前とページ付けする必要があります。

答えて

2

これに対して再帰的なクエリは必要ありません。

ゲット直接の親:

SELECT parent_id 
FROM link 
WHERE child_id = 5; 
┌───────────┐ 
│ parent_id │ 
├───────────┤ 
│   2 │ 
│   3 │ 
└───────────┘ 
(2 rows) 

兄弟取得:

SELECT b.child_id AS sibling_id 
FROM link a 
    JOIN link b USING (parent_id) 
WHERE a.child_id = 5 
    AND b.child_id <> 5; 
┌────────────┐ 
│ sibling_id │ 
├────────────┤ 
│   4 │ 
└────────────┘ 
(1 row) 

子供ゲット:

SELECT child_id 
FROM link 
WHERE parent_id = 5; 
┌──────────┐ 
│ child_id │ 
├──────────┤ 
│  6 │ 
└──────────┘ 
(1 row) 
+0

ありがとうございました。私はこのアイデアを持っていましたが、私は1つの質問でそれを行うことができると思いました。また、私は全体の結果を注文する必要があり、それは何百ものレコードになる可能性があります。 – SomethingElse

+0

もちろん、そうすることができます。 'ORDER BY'があります。 1つのクエリで実行したい場合は、各クエリの結果行数が異なるため、結果をどのように表示するかを指定する必要があります。たぶん['array_agg'](https://www.postgresql.org/docs/current/static/functions-aggregate.html)があなたが探しているものです。 –

1

これはあなたのすべての組み合わせを提供します(親/兄弟/子供) 。

select m.id, m.name,string_agg(distinct t.ids::text,',') 
from main_table m 
join linked_table l on l.childid = m.id or l.parentid = m.id 
join linked_table l3 USING(parentid), 
unnest(ARRAY[l.parentid,l.childid,l3.childid]) as t(ids) 
where t.ids <> m.id 
group by m.id, m.name 
order by m.name; 
+0

ありがとうございました。 Group Byは動作しません同じ名前の複数の行を表示しています – SomethingElse

+0

私は 'string_agg()'をクエリに追加しました。 –

関連する問題