1. ホーム
  2. sql

[解決済み】SQLで結合順は重要か?

2022-04-03 04:21:05

質問

パフォーマンスを無視して、以下のクエリ A と B で同じ結果が得られるでしょうか?CとDはどうでしょうか?

-- A
select *
from   a left join b
           on <blahblah>
       left join c
           on <blahblan>


-- B
select *
from   a left join c
           on <blahblah>
       left join b
           on <blahblan>  

-- C
select *
from   a join b
           on <blahblah>
       join c
           on <blahblan>


-- D
select *
from   a join c
           on <blahblah>
       join b
           on <blahblan>  

解決方法は?

対象 INNER の結合では、順序は重要ではありません。クエリは同じ結果を返しますが、selects を SELECT * から SELECT a.*, b.*, c.* .


の場合 ( LEFT , RIGHT または FULL ) OUTER の結合は、そうです、順序が重要です - そして、( 更新 )事態はもっと複雑です。

まず、外部結合は可換ではないので a LEFT JOIN b とは異なります。 b LEFT JOIN a

外側joinはassociativeではありません。

a LEFT JOIN b 
    ON b.ab_id = a.ab_id
  LEFT JOIN c
    ON c.ac_id = a.ac_id

は、以下のものと同等です。 :

a LEFT JOIN c 
    ON c.ac_id = a.ac_id
  LEFT JOIN b
    ON b.ab_id = a.ab_id

が、です。

a LEFT JOIN b 
    ON  b.ab_id = a.ab_id
  LEFT JOIN c
    ON  c.ac_id = a.ac_id
    AND c.bc_id = b.bc_id

とは同等ではありません。 :

a LEFT JOIN c 
    ON  c.ac_id = a.ac_id
  LEFT JOIN b
    ON  b.ab_id = a.ab_id
    AND b.bc_id = c.bc_id


もう一つ(できればもっと単純に)連想の例を挙げます。次のように考える。 (a LEFT JOIN b) LEFT JOIN c :

a LEFT JOIN b 
    ON b.ab_id = a.ab_id          -- AB condition
 LEFT JOIN c
    ON c.bc_id = b.bc_id          -- BC condition

これは は同等です から a LEFT JOIN (b LEFT JOIN c) :

a LEFT JOIN  
    b LEFT JOIN c
        ON c.bc_id = b.bc_id          -- BC condition
    ON b.ab_id = a.ab_id          -- AB condition

というのも、quot;nice"があるからです。 ON の条件を満たしています。どちらも ON b.ab_id = a.ab_idc.bc_id = b.bc_id は等値検査であり NULL を比較します。

他の演算子を使った条件や、もっと複雑な条件も可能です。 ON a.x <= b.x または ON a.x = 7 または ON a.x LIKE b.x または ON (a.x, a.y) = (b.x, b.y) というように、2つのクエリは等価であることに変わりはない。

しかし、これらのいずれかが IS NULL のようなヌルに関係する関数や COALESCE() という条件であった場合、例えば b.ab_id IS NULL この場合、2つのクエリーは等価ではありません。