2012-12-04 6 views
1

SQL의 테이블을 왼쪽에 쿼리가 ON column = constant 조건을 무시 가입 왼쪽 왼쪽 테이블에, 술어 "= 상수에"무시 가입 떠났다.
그러나 오른쪽 테이블에 다른 ON column = constant 조건자를 신경 쓰고 있습니다.SQL은/​​PostgreSQL은

대신 왼쪽 테이블의 ON column = constant을 WHERE 절로 이동하면 쿼리가 의도 한대로 작동합니다.

왼쪽 테이블에 대해 column = constant을 쿼리의 WHERE 부분 또는 쿼리의 JOIN ... ON 부분에 배치하면 왜 중요합니까?

은 (어떻게됩니까, 왼쪽 테이블이 ON column = constant 조건이 겉으로는 무시되고있는 "필터 가입하세요"단계까지 밀어 도착한다는 것입니다.)

세부 사항 : 여기

EXPLAIN ANALYZE 
select * from DW1_PAGE_PATHS t left join DW1_PAGES g 
    on t.TENANT = g.TENANT 
    and t.PAGE_ID = g.GUID 
    and g.GUID = 'abcdefg' -- works 
    and t.CANONICAL = 'C' -- "ignored", unless moved to `where` clause 
where t.TENANT = '72' 
    and PARENT_FOLDER like '/%'; 

(아래)는 임원 계획입니다. t.CANONICAL = 'C'은 "JOIN Filter"단계로 밀어 넣는 반면, g.GUID = 'abcdefg' 필터는 오른쪽 테이블을 스캔 할 때 직접 발생합니다.

Nested Loop Left Join (cost=... actual time=...) 
    Join Filter: (((t.canonical)::text = 'C'::text) 
      AND ((t.tenant)::text = (g.tenant)::text) 
      AND ((t.page_id)::text = (g.guid)::text)) 
    -> Seq Scan on dw1_page_paths t 
     Filter: (((parent_folder)::text ~~ '/%'::text) 
       AND ((tenant)::text = '72'::text)) 
    -> Seq Scan on dw1_pages g 
     Filter: (((tenant)::text = '72'::text) 
       AND ((guid)::text = 'abcdefg'::text)) 

(또 다른 질문 :?. 왜 정식이 'C'그것은하지 않습니다이되지 않은 필터 밖으로 행 t.canonical = 'C'와 '필터 참여 "하지 않습니다)

(. PostgreSQL의 버전 psql (9.1.6, server 9.1.1)) 여기

비슷한 쿼리에 대한 링크,하지만 작동 당신이 대신 where 절에 왼쪽 테이블 ON column = constant를 이동하면 왜 대답 을 설명하지 않습니다 : Add condition while using LEFT OUTER JOIN

답변

2

요점은 LEFT [OUTER] JOINON 절이 올바른 테이블의 행이 조인되는지 여부를 규제한다는 것입니다.

아니요, 왼쪽 표의 필터 행은입니다. 그렇게하고 싶으면 표현식은 WHERE 절 (이미 알았 듯이)이나 ON 절 ([INNER] JOIN)으로 이동해야합니다.
그게 전부입니다.

+0

이것은 의도적으로 설계된 표준 SQL입니까? (PostgreSQL뿐만 아니라) – KajMagnus

+0

@KajMagnus : 표준 SQL. 다른 RDBMS에서 동일한 방식으로 작동합니다. –