总的来说,我相信“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中没有对应行的任何Override行,选择覆盖值。
现在,通常我只会做一个三部分查询:
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 合理的情况,还是有比上述更好的选择?