2014-03-05 3 views
0

재귀 쿼리를 수행하는 데 사용해야하는 두 개의 테이블이있는 PostgreSQL DB가 있습니다.
두 표는 다음과 같다 :PostgreSQL JOIN 내부의 재귀 CTE 문제

Main table 
Box   pipeline plate solution 
---------------------------------------- 
X000001  Pipe  10000 75750 
X000001  Pipe  10000 75751 
X000001  Pipe  10001 75752 
X000001  Line  20000 75750 
Y000002  Pipe  10007 75800 
... 


Mixture (Solution History) 
made_solution_id  used_solution_id 
------------------------------------- 
75750    66746 
75750    73002 
66746    76380 
66746    80000 
... 

당신이 판에 여러 솔루션, 파이프 라인 당 여러 개의 판, 및 상자 당 여러 개의 파이프 라인을 가질 수 있습니다 볼 수있는 메인 테이블. 혼합 표는 여러 가지 용액을 사용하여 하나의 용액을 만든다 (예 : 66746과 73002를 사용하여 75750을 만들었다).

내가해야할 일은 모든 행에 대해 Mixture 테이블에 대한 재귀 쿼리를 수행하여 시작까지 모든 기록이 반환되도록하는 것입니다. 기본 테이블에서 첫 번째 행의

예 :

Box  pipeline plate made_solution_id  used_solution_id 
----------------------------------------------------------------- 
X000001 Pipe  10000 75750    66746 
X000001 Pipe  10000 75750    73002 
X000001 Pipe  10000 66746    76380 
X000001 Pipe  10000 66746    80000 

를 ... 주요의 모든 행이 작업을 수행 (솔루션을 만드는 데 사용 부모 솔루션이없는 재귀 때까지 모든 방법) 테이블

그래서 그 일을 위해,이 재귀 쿼리를 내놓았다 :

WITH RECURSIVE parents (box, pipeline, plate, made_solution_id, used_solution_id) 
AS (
    --get leaf solution 
    SELECT 
    box, pipeline, plate, made_solution_id, used_solution_id 
    FROM 
    main 
    JOIN 
    mixture 
    ON 
    solution = made_solution_id 

UNION 
    --get parent solutions 
    SELECT 
    t.box, t.pipeline, t.plate, m.made_solution_id, m.used_solution_id 
    FROM 
    main t 
    JOIN 
    parents pt 
    ON 
    pt.made_solution_id = t.solution 
    JOIN 
    mixture m 
    ON 
    pt.used_solution_id = m.made_solution_id 
) 
SELECT * from parents 

이,하지만 작동하지 않았다. 내 재귀 단계가 작동하지 않는 것 같습니다 - 쿼리가 Main 테이블의 모든 행을 통과하지만 Main 테이블과 Mixture 테이블 사이의 JOIN 결과를 반환합니다.

그래서 그 대신의 예는 위의 결과처럼 보이는, 그것은이 대신 다음과 같습니다 내가 잘못 뭐하는 거지

Box  pipeline plate made_solution_id  used_solution_id 
----------------------------------------------------------------- 
X000001 Pipe  10000 75750    66746 
X000001 Pipe  10000 75750    73002 

? 재귀 쿼리 문건을 읽고 재귀 CTE에 대한 여러 질문을 살펴 보았습니다.

편집 : 그런데 어윈 Brandstetter http://www.sqlfiddle.com/#!11/9354f/4

의 PostgreSQL 버전 8.4.17에서 제공하는 SQL 쿼리와 바이올린의 변경 뭔가.

EDIT2 : 이것은 내 쿼리가 psql의에 반환 무엇의 일부입니다

XYZ01 | High | 114043 |    49923 |    46573 
XYZ01 | High | 115424 |    49923 |    46573 
XYZ01 | High | 114043 |    46573 |    39853 
XYZ01 | High | 115424 |    46573 |    39853 
XYZ01 | High | 114043 |    46573 |    20456 
XYZ01 | High | 115424 |    46573 |    20456 
XYZ01 | High | 116694 |    49923 |    46573 
XYZ01 | High | 116691 |    49923 |    46573 
XYZ01 | High | 116697 |    49923 |    46573 
XYZ01 | High | 116693 |    49923 |    46573 
XYZ01 | High | 116696 |    49923 |    46573 
XYZ01 | High | 116699 |    49923 |    46573 
XYZ01 | High | 116698 |    49923 |    46573 
XYZ01 | High | 116692 |    49923 |    46573 
XYZ01 | High | 116695 |    49923 |    46573 

어떤 : (참고 :이 재귀 쿼리가 단지 몇 행 후 재귀 일에 일을 중단 한 예입니다). .. 바이올린이 돌아 오는 것이 아닙니다.

+0

는 난 단지 *을 첨가 한 후 상기 recursvie CTE 테이블과 메인 테이블에 _that_의 결과에 가입 * 통과 할 재귀 CTE를 사용합니다. –

+0

@a_horse_with_no_name 주 테이블의 행마다 솔루션을 만드는 데 사용되는 몇 가지 솔루션 (및 해당 상위 솔루션 사용)에 대해 생각해 보았습니다. 어떻게 상자를 추적 할 것입니까? , 파이프 라인, 정보 등 내가 그렇게한다면? 그 상자, 파이프 라인, 판자가 그 부모가 속할 것임을 알아야합니다. (상자가 여러 개있을 수도 있습니다.)나는 혼합 테이블에서만 반복적 인 cte를 사용하여 그 일을 할 수있는 방법을 보지 못했다. – Joe

+1

테이블'box' (또는 적절한 테이블 정의)에 대한 정의가 표시되지 않습니다. 또한 : Postgres 버전? 이상적으로, 당신은 SQL Fiddle에 이것을위한 테스트 케이스를 제공 할 것이다. [이 스텁] (http://www.sqlfiddle.com/#!15/803b9)을 기반으로 구축 할 수 있습니다. –

답변

1

CTE의 두 번째 부분에서 t가 아닌 m 상자를 파이프 라인으로 반환해야합니다. 그렇지 않으면 솔루션을 거치게 될 것입니다. 그렇지만 남은 부분에 대해 현재 표시하고있는 정보를 표시하지는 않습니다 (사용자가 원하는 것처럼 보입니다). 대신 첫 번째 메시지 만 표시합니다.

WITH RECURSIVE parents (box, pipeline, plate, made_solution_id, used_solution_id) 
AS (
    --get leaf solution 
    SELECT 
    box, pipeline, plate, made_solution_id, used_solution_id 
    FROM 
    main 
    JOIN 
    mixture 
    ON 
    solution = made_solution_id 

UNION 
    --get parent solutions 
    SELECT 
    m.box, m.pipeline, m.plate, m.made_solution_id, m.used_solution_id 
    FROM 
    main t 
    JOIN 
    parents pt 
    ON 
    pt.made_solution_id = t.solution 
    JOIN 
    mixture m 
    ON 
    pt.used_solution_id = m.made_solution_id 
) 
SELECT * from parents