FULL OUTER JOIN 在这里真的是一件坏事吗?

Posted

技术标签:

【中文标题】FULL OUTER JOIN 在这里真的是一件坏事吗?【英文标题】:Is FULL OUTER JOIN really such a bad thing here? 【发布时间】:2010-11-15 04:57:21 【问题描述】:

一般来说,我相信“FULL OUTER JOIN Considered Harmful”,转而使用这句话。

背景:

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 是合理的吗,还是有比上述情况更好的替代方案?

【问题讨论】:

【参考方案1】:

你想在这里完全加入,所以我认为它根本不会被认为是有害的。这是获得解决方案集的最佳方式。我会在每种方式上运行查询执行播放以查看哪个最快,但我的猜测是完全连接会是。

请记住,在处理外连接时,where 子句中的条件与 join 子句中的条件之间存在明显区别。 Where 限制整个结果集,join 限制匹配的行。

【讨论】:

以上是关于FULL OUTER JOIN 在这里真的是一件坏事吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 MySQL 中进行 FULL OUTER JOIN?

如何在 MySQL 中进行 FULL OUTER JOIN?

oracle的full outer join如何排除掉空值

sql MS SQL Full Outer Join

Oracle表与表之间的连接方式(内连接:inner join 外连接 全连接: full outer join左连接:left outer join 右连接:right outer join(代码

SQL的JOIN语法解析(inner join, left join, right join, full outer join的区别)