2014-02-18 3 views
1

최근에 postgreSQL에서 recursive query을 요청했습니다. 대답은 잘 맞는,하지만 곧 내가 가입 요소를 추가, 그것은 나에게 다음과 같은 오류 제공 : 나는 몇 가지 수정을 시도JOIN 요소가있는 순환 체인?

ERROR: missing FROM-clause entry for table "n": WITH RECURSIVE chain AS (SELECT n.pordnr, pz.pordnrzu, n.abschl, n.stg, n.kzfa, n.pversion FROM pord n LEFT JOIN pordnrzu pz ON pz.pordnr = n.pordnr WHERE n.pordnr = 112 UNION ALL SELECT n.pordnr, pz2.pordnrzu, n.abschl, n.stg, n.kzfa, n.pversion FROM chain c LEFT JOIN pordnrzu pz2 ON pz2.pordnr = n.pordnr INNER JOIN pord n ON (c.pordnrzu = n.pordnr) WHERE c.abschl IS NULL) SELECT * FROM chain c WHERE c.abschl IS NOT NULL

을하지만 난 그게 동작하지 않습니다. 내가 원하는 것은 pordnrzu이 구현되어 다른 pordnr을 찾는다는 것입니다.

그래서 : pordnr ->pordnrzu ->pordnr

난 그냥 놓친 있나요? 지금

CREATE TABLE pord (
    pordnr integer primary key, 
    abschl text, 
    stg text, 
    kzfa text, 
    pversion text 
); 

INSERT INTO pord (pordnr, abschl, stg, kzfa, pversion) 
VALUES 
(112,  NULL, NULL, NULL, NULL), 
(140,  NULL, NULL, NULL, NULL), 
(200,  NULL, NULL, NULL, NULL), 
(210,  'f2', '140', 'H', '2011'), 
(220,  'f2222', '140000', 'HHH', '201111'); 

CREATE TABLE pordnrzu (
    pordnr integer primary key, 
    pordnrzu integer 
); 

INSERT INTO pordnrzu (pordnr, pordnrzu) 
VALUES 
(112,  140), 
(140,  210), 
(200,  220), 
(210,  220), 
(220,  NULL); 

그리고이 내 쿼리 :

는 샘플 테이블

WITH RECURSIVE chain AS 
(
    SELECT n.pordnr, pz.pordnrzu, n.abschl, n.stg, n.kzfa, n.pversion 
    FROM pord n 
    LEFT JOIN pordnrzu pz 
    ON pz.pordnr = n.pordnr 
    WHERE n.pordnr = 112 
    UNION ALL 
    SELECT n.pordnr, pz2.pordnrzu, n.abschl, n.stg, n.kzfa, n.pversion 
    FROM chain c 
    LEFT JOIN pordnrzu pz2 
    ON pz2.pordnr = n.pordnr 
    INNER JOIN pord n ON (c.pordnrzu = n.pordnr) 
    WHERE c.abschl IS NULL 
) 
SELECT * 
FROM chain c 
WHERE c.abschl IS NOT NULL; 

내 목표는 내가 그때까지 다른 pordnrpordnrzu 당 리드 pordnr=112, 시작이다 abschl NOT NULL으로 첫 번째 항목을 찾습니다.

이 예제에서 솔루션은 b 전자이 행 :

pordnr pordnrzu abschl stg kzfa pversion 
200  210  f2  140 H  2011 

SELECT version(); 

PostgreSQL 9.2.6 on x86_64-unknown-linux-gnu, compiled by gcc (SUSE Linux) 4.3.4 [gcc-4_3-branch revision 152973], 64-bit

답변

1

JOIN 절을 left-to-right을 평가됩니다. 두 번째는이 작업을 위해 가입 이동 :

WITH RECURSIVE chain AS (
    SELECT n.pordnr, pz.pordnrzu, n.abschl, n.stg, n.kzfa, n.pversion 
    FROM pord n 
    LEFT JOIN pordnrzu pz ON pz.pordnr = n.pordnr 
    WHERE n.pordnr = 112 

    UNION ALL 
    SELECT n.pordnr, pz.pordnrzu, n.abschl, n.stg, n.kzfa, n.pversion 
    FROM chain c 
    JOIN pord n ON n.pordnr = c.pordnrzu 
    LEFT JOIN pordnrzu pz ON pz.pordnr = n.pordnr 
    WHERE c.abschl IS NULL 
) 
SELECT * 
FROM chain c 
WHERE c.abschl IS NOT NULL; 

을 다른 방법으로, 1 일을 다시 할 수있는 2 SELECT에 가입 : 그것에 대해

LEFT JOIN pordnrzu pz ON pz.pordnr = c.pordnrzu
+0

좋아, 작동, 감사합니다! 두 번째 SELECT에서 두 번째 JOIN이 필요한 이유를 설명해 주시겠습니까? 그거 좋을거야. :) – Trollwut

+0

다음 '포드 (pord)'에서 데이터를 검색하려면 그 데이터에 참여해야합니다. 더 설명 할 것이 확실하지 않은가요? 나는 대안을 추가했다 ... –

+0

잘 됐어, 알았다. :) 그러나 나는 왜 내가 이전 질문에 그것을 필요로하지 않았는지 알지 못한다. https://stackoverflow.com/questions/21674589/recursive-query-in-postgresql하지만 지금은 머리 글자가 많아서 다시 읽으겠습니다. : D 귀하의 도움에 다시 한번 감사드립니다! – Trollwut