2013-01-10 1 views
18

여러 수준, 부모 및 차일드로 저장된 항목이있는 master 테이블이 하나 있는데 추가 데이터가 있거나 없을 수있는 두 번째 테이블이 있습니다. 내 마스터 테이블에서 두 수준을 쿼리하고 내 두 번째 테이블에 왼쪽 조인이 필요하지만 내 쿼리 내에서 순서 때문에이 작동하지 않습니다.하나의 쿼리에서 여러 테이블에 여러 개의 왼쪽 조인

SELECT something FROM master as parent, master as child 
    LEFT JOIN second as parentdata ON parent.secondary_id = parentdata.id 
    LEFT JOIN second as childdata ON child.secondary_id = childdata.id 
WHERE parent.id = child.parent_id AND parent.parent_id = 'rootID' 

왼쪽 조인은 from 절의 마지막 테이블에서만 작동하므로 왼쪽 조인 중 하나에서만 작동하게 할 수 있습니다. 위의 예에서 첫 번째 왼쪽 조인은 from 절의 첫 번째 테이블을 가리키고 두 번째 조인은 결코 이와 같이 작동하지 않으므로 왼쪽 조인 중 아무 것도 작동하지 않습니다.

어떻게하면됩니까? 쿼리의

+6

혼합 "이전 스타일" "새로운 스타일"을 (좌 가입 (FROM 절에 두 개의 테이블 이름)처럼 할 수 ...ON)은 거의 눈물로 끝날 것입니다. 다시 작성하고 WHERE 절을 살펴보십시오. 실제로는 제거하지 않으려는 행을 제거 할 수 있습니다. –

답변

29

이런 종류의 작업을해야합니다 - 명시 적으로 ANSI JOIN 구문을 다시 작성 후 :

SELECT something 
FROM master  parent 
JOIN master  child ON child.parent_id = parent.id 
LEFT JOIN second parentdata ON parentdata.id = parent.secondary_id 
LEFT JOIN second childdata ON childdata.id = child.secondary_id 
WHERE parent.parent_id = 'rootID' 

여기 트립 와이어는 명시 적 JOIN는 "이전 스타일"쉼표로 CROSS JOIN (,) 전에 결합이다. 어떤 경우에는 JOIN

I quote the manual here:FROM -list 상품 분리 콤마보다 긴밀하게 결합한다.

첫 번째 재 작성 후, 모두 왼쪽에서 오른쪽으로 적용 조인 (논리적 - 포스트 그레스는 달리 쿼리 계획에 테이블을 재 배열 할 무료입니다) 그리고 그것은 작동합니다.

그냥 내 지점을 만들기 위해,이 역시 작동합니다 : 귀하의 경우 다시 한번 설명으로

SELECT something 
FROM master parent 
LEFT JOIN second parentdata ON parentdata.id = parent.secondary_id 
,  master child 
LEFT JOIN second childdata ON childdata.id = child.secondary_id 
WHERE child.parent_id = parent.id 
AND parent.parent_id = 'rootID' 

그러나 명시 적 JOIN 구문은 일반적으로 바람직하다.

그리고 여러 (좌) 행 곱할 수 조인 알고 있어야 :

2

JOIN 문은 또한 FROM 조항의 일부, 더 공식적으로 join_type이에 사용됩니다 두 개를 합치십시오 from_item을 하나에 넣으십시오 from_item 그 중 여러 개는 쉼표로 구분 된 목록을 작성할 수 있습니다. r FROM. http://www.postgresql.org/docs/9.1/static/sql-select.html을 참조하십시오.

그래서 문제에 대한 직접적인 해결책은 : 이미 제안 된 같은 단지, JOIN 's을 (를) 사용에

SELECT something 
FROM 
    master as parent LEFT JOIN second as parentdata 
     ON parent.secondary_id = parentdata.id, 
    master as child LEFT JOIN second as childdata 
     ON child.secondary_id = childdata.id 
WHERE parent.id = child.parent_id AND parent.parent_id = 'rootID' 

더 좋은 옵션이 될 것입니다.

4

당신이

SELECT something 
FROM 
    (a LEFT JOIN b ON a.a_id = b.b_id) LEFT JOIN c on a.a_aid = c.c_id 
WHERE a.parent_id = 'rootID' 
+3

@DeniseMeander : 왜이 ​​대답이 받아 들여지는지 모르겠다. 이전 질문에 새로운 내용을 추가하지 않고 괄호를 제외하고는이 경우 소음 일뿐입니다. 그리고 아무 설명도. 명시 적 조인은 기본적으로 왼쪽에서 오른쪽으로 실행됩니다 (조인 조건이 다른 순서를 강제하지 않는 한). –

+0

@ErwinBrandstetter이 대답은 더 명확합니다. 테이블 이름에 공백이 있기 때문에 혼란 스럽습니다. – kahonmlg

+1

@kahonmlg : 테이블 이름에 공백이 없습니다. 테이블 별명을 잘못 해석 한 것일 수 있습니다. 참조 : https://stackoverflow.com/a/11543614/939860 –