一般的に、私は「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. */
と:
CREATE TABLE Overrides(c1, c2, c3, fordate)
このロジックに従うには、上記のビューを調整する必要があります。
- 計算された日付に対応するオーバーライドがないCalcs行については、計算された値を選択します。
- 計算された日付がオーバーライド日付と一致するCalcs行については、オーバーライド値を選択します。
- Calcsに対応する行がないオーバーライド行については、オーバーライド値を選択します。
さて、通常は 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 が正当化される状況ですか、それとも上記のものよりも優れた代替手段がありますか?