흠, 전에 이런 식으로 일을 해왔다고 생각합니다. 그 당시에는 계층이 있었고 문제는 "노드 X의 모든 자식과 손자를 찾으십시오."였습니다. 관계형 데이터베이스에서는 그렇게하기가 쉽지 않습니다. 그래서 헬퍼 테이블과 스크립트를 작성했습니다. 내가 그것을 기억할 수 있는지 보자 ... 참고 : 이것은 내 기억 후 자유로 우며 테스트되지 않았으므로 아무런 보증도하지 않는다. 내 문제는 너의 것과 약간 다르므로 솔루션이 적용되는지 잘 모르겠습니다. 이 표는 머리와 꼬리가 외부 키 인 상태, 모든 가능한 링크를 포함하는
create table chain_helper (
head int,
tail int,
chain_length int
)
create index chain_helper_by_head(head);
create index chain_helper_by_tail(tail);
생각입니다. 내 사례는 엄격한 계층 구조를 가지고 있었기 때문에 조금 쉬웠다. 루프 제어가 필요하지 않았다. 원본 테이블에는 id 및 parent_id 필드가 있습니다.간단한 링크
초기화 테이블 : 저는 여기에 테이블을 채워 어떻게 내가 길이 2의 모든 체인 테이블을 채우는 계속
insert into chain_helper (head, tail, chain_length)
select id, parent_id, 1 from source_table;
:
insert into chain_helper (head, tail, chain_length)
select parent.head, child.tail, min(parent.chain_length + 1)
from chain_helper parent
join source_table child on source_table.parent_id=parent.id
where not exists
(select * from chain_helper where head=parent.head and tail=child.tail)
group by parent.head, child.tail;
(내가 가진 이후 엄격한 계층 구조, 나는 집계 할 필요가 없었다 - 나의 경우에는 중복이 없을 것이다).
반복하면 길이가 3 인 모든 체인이 삽입되며 삽입 할 내용이 없을 때까지 명령문을 모두 반복 할 수 있습니다. 그런 다음 최대 체인 길이를 찾기 위해 사소한 :
select max(chain_length) from chain_helper;
이 솔루션은 쉽게 체인을 표시하지 않습니다 -하지만 내 경우에는 요구 사항이 아니었다. 계층 구조의 특정 노드의 모든 자식과 손자 잡을 수 있도록 조인에 나는 주로 chain_helper을 사용 - "이 하위 트리에 대한 총 수익"즉 :
select sum(source_table.revenue)
from source_table join chain_helper on chain_helper.tail = source_table.id
where chain_helper.head = parent_of_subtree;
당신은 postgres 'RECURSIVE 성명서를 들여다 보았습니까? 당신은 당신이 그것을 사용하기를 바랄 수 있기를 바랄 수 있습니다. –
크기는 큽니다. 테이블을 읽고 명백한 방식으로 연결된 목록을 작성하는 것이 가장 쉬울 것입니다. 그런 다음 가장 긴 목록을 찾습니다. SQL에서는 일련의 쿼리를 수행 할 것이라고 확신합니다. 길이 N의 가장 긴 체인에 대한 로그 N 쿼리에서 수행 할 수 있어야합니다. 길이가 2, 4, 8 등인 체인을 찾을 때까지 요소가 0 인 길이 2^i를 찾을 수 있습니다. 그러면 이진 탐색은 2^(i-1)과 2^i - 1 사이에서 가장 긴 것을 찾습니다. – Gene
이 문제는 이분 그래프에 대한 가장 긴 경로 문제를 줄이면 NP 하드가되는 것으로 알려져 있습니다. 큰 데이터베이스에서이 문제를 해결할 수있는 빠른 알고리즘을 찾으십시오. – templatetypedef