【问题标题】:FULL OUTER JOIN value conditionFULL OUTER JOIN 值条件
【发布时间】:2012-02-13 00:21:45
【问题描述】:

我需要为 FULL OUTER JOIN 添加值条件。

即我正在尝试这样做:

SELECT *
FROM Table1
FULL OUTER JOIN Table2 ON Table1.Field1 = Table2.Field1 AND Table2.Field2 > 5

但是这个脚本不起作用。实际上看起来条件(Table2.Field2 > 5)根本没有应用。

RIGHT OUTER JOIN 也出现了同样的问题,所以我认为原因是当存在 RIGHT 或 FULL 连接时,连接中的右表没有应用值条件。
为什么会这样?对这种行为有概念上的解释吗?

当然,主要问题是如何解决这个问题。

有没有办法在不使用子查询的情况下解决这个问题?

SELECT *
FROM Table1
FULL OUTER JOIN (SELECT * FROM Table2 WHERE Table2.Field2 > 5) AS t2 ON Table1.Field1 = t2.Field1

【问题讨论】:

    标签: sql join outer-join full-outer-join


    【解决方案1】:

    这曾经让我感到困惑。现在我懂了! “on”之后的条件(在您的情况下:Table1.Field1 = Table2.Field1 AND Table2.Field2 > 5 )告诉连接运算符两个表中的哪些行被连接。这意味着当且仅当 table1 中的 row1 和表中的 row2 满足 row1.field1 = row2.field2 和 row2.field2 > 5 时,才会连接 row1 和 row2。其余行未连接。

    因此,在完全外连接中,结果集将是连接行、table1 中的非连接行和 table2 中的非连接行。 在右连接中,结果集将是来自 table2 的连接行和非连接行。 在任何一种情况下,表 2 中字段 2

    这就是为什么“Table2.Field2 > 5”在左连接中正常工作,但在右连接或完全连接中却不是“正常”,但值条件确实在正确地工作。

    【讨论】:

      【解决方案2】:

      相当复杂,但没有子查询

      SELECT  Table1.*
              , CASE WHEN Table2.Field2 > 5 THEN Table2.Field1 ELSE NULL END
              , CASE WHEN Table2.Field2 > 5 THEN Table2.Field2 ELSE NULL END        
      FROM    Table1
              FULL OUTER JOIN Table2 ON Table1.Field1 = Table2.Field1
      WHERE   COALESCE(Table2.Field2, 6) > 5
              OR Table1.Field1 = Table2.Field1
      

      测试脚本

      ;WITH Table1 AS (
        SELECT * FROM (VALUES
          (1, 1)
          , (2, 2)
          , (5, 5)
          , (6, 6)
        ) AS Table1 (Field1, Field2)
      )
      , Table2 AS (
        SELECT * FROM (VALUES
          (1, 1)
          , (3, 3)
          , (4, 4)
          , (5, 5)
          , (7, 7)
        ) AS Table2 (Field1, Field2)
      )
      SELECT  Table1.*
              , CASE WHEN Table2.Field2 > 5 THEN Table2.Field1 ELSE NULL END
              , CASE WHEN Table2.Field2 > 5 THEN Table2.Field2 ELSE NULL END        
      FROM    Table1
              FULL OUTER JOIN Table2 ON Table1.Field1 = Table2.Field1
      WHERE   COALESCE(Table2.Field2, 6) > 5
              OR Table1.Field1 = Table2.Field1
      

      结果

       Field1 Field2 Field1 Field2
       1      1      NULL   NULL
       5      5      NULL   NULL
       NULL   NULL   7      7
       6      6      NULL   NULL
       1      1      NULL   NULL
       2      2      NULL   NULL
      

      【讨论】:

      • 谢谢,但这仍然不是我想要的解决方案。虽然这种方法节省了查询结构(对我来说很重要,因为 SQL 语句是自动生成的),所以它比以前的解决方案更合适。仍然有很多额外的代码,所以也许我最终必须实现子查询解决方案。但是这个解决方案已经足够好了,所以我想我可以接受它作为答案。
      【解决方案3】:

      你想要的可能会被重新表述为:

       SELECT *
         FROM Table1
         LEFT JOIN Table2 ON Table1.Field1 = Table2.Field1 AND Table2.Field2 > 5
        UNION ALL
       SELECT *
         FROM Table1
        RIGHT JOIN Table2 ON Table1.Field1 = Table2.Field1
        WHERE Table2.Field2 > 5
          AND Table1.Field1 IS NULL
      

      但是按照自己的建议使用子查询是 IMO 的最佳选择。

      【讨论】:

      • 感谢您的建议,但这对我来说不是一个好的解决方案。没错,它会起作用,但这比简单的子查询还要复杂。
      • @SergeyT:你不带子查询的问,我不带子查询的回答。您的解决方案可能是最好的选择。根据 RDBMS,您可以将其放入 WITH 子句中。
      猜你喜欢
      • 2019-08-07
      • 1970-01-01
      • 1970-01-01
      • 2013-03-10
      • 2019-01-27
      • 2020-05-25
      • 1970-01-01
      • 2011-09-28
      • 2020-03-03
      相关资源
      最近更新 更多