SQL 左 联接查询将忽略 左 表ON column = constant上的谓词。 但是,它关心 右 表中的另一个谓词。 ON column = constant
ON column = constant
如果我ON column = constant改为将左表移至WHERE子句,则查询将按预期工作。
对于左表,如果将放置column = constant在查询的WHERE部分或查询的JOIN … ON部分中,为什么有关系呢?
column = constant
(发生的情况是,左表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'已将其推至“ JOIN筛选器”步骤,而g.GUID = 'abcdefg'筛选器将在扫描右表时直接发生。
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)。)
psql (9.1.6, server 9.1.1)
这是指向类似查询的链接,但是答案不能解释 为什么 将左表ON column = constant移到where子句时它可以起作用: 使用LEFT OUTER JOIN时添加条件
where
关键是,“仅”ON子句LEFT [OUTER] JOIN规定了是否连接右表中的行。
ON
LEFT [OUTER] JOIN
它 不是 左表过滤行。如果要执行此操作,则表达式必须进入WHERE子句(如您已经发现的那样)或a的ON子句中[INNER] JOIN。 这都是设计使然。
WHERE
[INNER] JOIN