2009-07-29 14 views
3

一般的に、私はフレーズを回すために、 "FULL OUTER JOINは有害だと考えています"と信じています。FULL OUTER JOINは本当にここの悪いことですか?

背景:

http://weblogs.sqlteam.com/jeffs/archive/2007/04/19/Full-Outer-Joins.aspx

しかし、私はそれは次のようになり、特定の状況本当に便利持っています:考える

CREATE VIEW Calcs(c1, c2, c3, fordate, ...other columns) AS 
    /* Complicated set of equations, etc. */ 

そして:

をその計算された日付は対応するオーバーライドを持っていない、計算された値を選択した任意の CALCS行の場合

  1. :私はに必要

    はこのロジックに従うことを上記表示を調整します。

  2. Calc計算された日付がで、一致する行がとオーバーライドされた場合は、上書きする値を選択します。
  3. の対応する行がない行をCalcに上書きするには、オーバーライド値を選択します。今

、通常、私は3つの部分クエリだけだろう:

CREATE VIEW Calcs AS ... (current logic) 

CREATE VIEW CalcsWithOverrides AS 

    SELECT * FROM Calcs WHERE NOT EXISTS (match in Overrides) 

    UNION ALL 

    SELECT override.c1, override.c2, override.c3, (other non-overridden columns) 
     FROM Calcs INNER JOIN Overrides 

    UNION ALL 

    SELECT *, (null placeholders for non-overridden columns) FROM Overrides WHERE 
     NOT EXISTS (match in Calcs) 

そして、まだ、はるかに少ない簡単なOUTER JOINを使用するよりもようだ:

SELECT 
     COALESCE(Calcs.fordate, Overrides.fordate) AS fordate, 
     -- Note that I am not using COALESCE() below on purpose: a null override should still override any calculated value 
     CASE WHEN Overrides.fordate IS NULL THEN Calcs.c1 ELSE Overrides.c1 END AS C1, 
     CASE WHEN Overrides.fordate IS NULL THEN Calcs.c2 ELSE Overrides.c2 END AS C2, 
     CASE WHEN Overrides.fordate IS NULL THEN Calcs.c3 ELSE Overrides.c3 END AS C3, 
     (....other columns from calcs that will be null for override-only rows...) 
    FROM 
     Calcs 
     FULL OUTER JOIN Overrides ON Overrides.fordate = Calcs.fordate 

ので、さこれはOUTER JOINが正当化されている状況、または上記のものよりもの方が良いです。

答えて

8

ここに完全参加したいので、それはまったく有害ではないとは思いません。それがあなたのソリューションセットに到達する最良の方法です。私はどの方法が最も速いのかを見るためにそれぞれの方法でクエリ実行を実行しますが、私の推測では完全な結合が行われることになります。

外部結合を処理する場合、where句の条件とjoin句の条件の間に明確な違いがあることを覚えておいてください。 Whereは結果セット全体を制限し、joinは一致する行を制限します。

+0

最後の文(本当に)は悪い思い出を持ち帰った.... – dverespey

+0

lol @ dverespey - そこにされたこと – richardtallent

関連する問題