4

SQL左結合クエリは、テーブルのON column = constant述語を無視します。ただし、右側のテーブルの別の述語を 気にします。
ON column = constant

代わりに左側のテーブルON column = constantを WHERE 句に移動すると、クエリは意図したとおりに機能します。

column = constant左側のテーブルで、クエリの WHERE 部分またはクエリの JOIN ... ON 部分にを配置すると、なぜ問題になるのでしょうか?

(何が起こるかというと、左側のテーブルON column = constant条件が「JOIN フィルター」ステップにプッシュされ、無視されているように見えます。)

詳細:

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'を指定した "結合フィルター" が、 canonicalが 'C' ではない行を除外しないのはなぜですか? そうではありません。)

(PostgreSQL のバージョンpsql (9.1.6, server 9.1.1)。)

同様のクエリへのリンクを次に示しますが、代わりに左のテーブルを句に 移動した場合に機能する理由が回答で説明されていません: Add condition while using LEFT OUTER JOINON column = constantwhere

4

1 に答える 1

5

要点は、ONa only の句がLEFT [OUTER] JOIN、右側のテーブルの行が結合されるかどうかを規制することです。

左側のテーブルの行はフィルター処理されません。あなたがそれをしたいなら、式はWHERE句(あなたがすでに知っているように)または のON句に入らなければなりません[INNER] JOIN.
それはすべて設計によるものです。

于 2012-12-04T10:37:37.550 に答える