2017-03-13 1 views
0

나는 many to many 관계를 가지고 있습니다. 예 : 한 명의 주 부모는 여러 자녀를 가질 수 있으며 그 자녀는 여러 부모를 가질 수 있습니다.PostgreSQL에서 나무를 얻으십시오

내 주요 표는

| 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 

입니다 그리고

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

지금 나는 모든 직접 부모, 형제 자매 주어진 항목의 직접 아이를 얻고 싶은처럼 연결된 테이블이 보인다. 예를 들어 ID가 5 인 경우 2,3, 4 및 6을 가져오고 싶습니다. PostgreSQL에서는 새로운 기능을 제공합니다. 하나의 쿼리에서 어떻게 할 수 있습니까? 결과를 이름순으로 정렬하고 페이지 매김을해야합니다.

답변

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

대단히 감사합니다. 이 아이디어가 있었지만 한 가지 질문으로 생각할 수 있다고 생각했습니다. 또한 전체 결과를 주문해야하며 수백 건의 레코드가 될 수 있습니다. – SomethingElse

+0

물론 가능합니다. 'ORDER BY'가 있습니다. 하나의 쿼리에서이 작업을 수행하려면 각 쿼리에 대해 결과 행의 수가 서로 다르기 때문에 결과를 표시하는 방법을 지정해야합니다. 어쩌면 ['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()'를 쿼리에 추가했습니다. –