sql-server - FULL OUTER JOIN 真的是一件坏事吗?

标签 sql-server tsql 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. */

还有:

CREATE TABLE Overrides(c1, c2, c3, fordate)

我需要调整上面的 View 以遵循以下逻辑:

  1. 对于计算日期没有相应覆盖的任何计算行,请选择计算值。
  2. 对于计算日期与覆盖日期匹配的任何计算行,请选择覆盖值。
  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 是否合理,或者是否有比上述方法更好的替代方案?

最佳答案

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

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

关于sql-server - FULL OUTER JOIN 真的是一件坏事吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1202477/

相关文章:

sql-server - 使用 SqlBulkCopy 插入 sql_variant 列时如何设置列类型

sql - 如何选择(其他表)中的位置但进行修改

r - 如何在R中执行大型数据集的完全外部联接?

c# - 在开发计算机上运行 azure web 应用程序时出现数据库访问错误

SQL Server 2005 'between' 运算符(operator)行为 - bug 还是功能?

使用 DateDiff 时的 SQL 动态 DatePart

sql - 两个值如何相等但又不相等?

MySQL 使用内连接进行更新

c# - Linq to Sql 本地化查询

mysql - 用于查找缺失条目的 SQL 查询