SQL左连接查询忽略左表ON column = constant
上的谓词。
但是,它关心右表上的另一个谓词。ON column = constant
如果我将左表ON column = constant
移至 WHERE 子句,则查询将按预期工作。
column = constant
对于左表,如果我将放在查询的 WHERE 部分或 JOIN ... ON 部分,为什么这很重要?
(发生的情况是,左表ON column = constant
条件被推到“JOIN Filter”步骤,似乎被忽略了。)
细节:
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'
它已被推到“加入过滤器”步骤,而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))
(另一个问题:为什么使用t.canonical = 'C'的“加入过滤器”不会过滤掉规范不是“C”的行?它不会。)
(PostgreSQL 版本psql (9.1.6, server 9.1.1)
。)
这是一个类似查询的链接,但答案并没有解释为什么如果您将左表ON column = constant
移到where
子句中它会起作用:
Add condition while using LEFT OUTER JOIN