一尘不染

SQL / PostgreSQL左连接忽略左表上的``n =常量''谓词

sql

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'已将其推至“ JOIN筛选器”步骤,而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子句时它可以起作用:
使用LEFT OUTER JOIN时添加条件


阅读 199

收藏
2021-03-17

共1个答案

一尘不染

关键是,“仅”ON子句LEFT [OUTER] JOIN规定了是否连接右表中的行。

不是 左表过滤行。如果要执行此操作,则表达式必须进入WHERE子句(如您已经发现的那样)或a的ON子句中[INNER] JOIN
这都是设计使然。

2021-03-17