【问题标题】:Full outer join not bringing all results SQL-Server完全外连接不会带来所有结果 SQL-Server
【发布时间】:2018-02-05 12:39:44
【问题描述】:

我在尝试从联接中检索所有结果时遇到问题。我在 SQL fiddle 中设置了一个类似的场景,它可以工作,但在 SQL Server 中却不行。如果开具发票或发货,我想为所有内容提供结果。

我在 SQL-SERVER 中得到的结果是

|  No | Order1 | Shipdate |     No | Order1 |  InvDate |
|-----|--------|----------|--------|--------|----------|
| 111 |    222 | 17-01-18 |    111 |    222 | 24-01-18 |
| 222 |    333 | 18-01-18 |    222 |    333 | 24-01-18 |

即使将连接更改为完全外部,右连接我仍然会得到这个结果。

我原以为如果我使用完整的外部,无论匹配如何,它都会带回所有结果,但事实并非如此。

我缺少什么来给我完整的外部结果?谢谢

sql 小提琴 - http://sqlfiddle.com/#!18/89943/1

【问题讨论】:

  • 你的小提琴只包含一个左连接...!?
  • 如果你想得到所有结果,你可以使用交叉连接。
  • @daniel.shih CROSS JOIN OUTER JOIN 非常不同。仍然尝试根据提供的ON 子句(OUTER JOIN)关联数据集,但如果没有建立关联,仍会从双方返回行。但是,另一个使用两个数据集 (CROSS JOIN) 中的所有数据创建笛卡尔积。
  • @Larnu 谢谢你的提醒 :)
  • “它可以工作,但在 SQL Server 中它不能”和“将连接更改为完全外部右连接”没有意义。 “为所有事情带来结果”和“无论匹配如何都带回所有结果”尚不清楚。您的文字不清楚,并且您没有为您的输入显示所需的输出。请编辑清楚。这包括minimal reproducible example。 PS Full join 是left join union right join。左连接是内连接行加上由空值扩展的不匹配的左表行。您使用的是什么参考?

标签: sql sql-server join left-join


【解决方案1】:

这是您的查询:

SELECT S.No, s.Order1, s.Shipdate, i.No, i.Order1, i.InvDate 
FROM Ship S LEFT JOIN
     Invoice I
     ON s.No=i.No AND s.Order1 = i.Order1
WHERE S.Person = 1;

LEFT JOIN 更改为FULL JOIN 不会改变任何内容。 WHERE 子句将FULL JOIN 转换为LEFT JOIN,因为该表上不匹配的行具有NULL 值并且不符合WHERE 条件。

【讨论】:

    【解决方案2】:

    OUTER JOIN 查询可以设置如下:

    SELECT
        S.No, s.Order1, s.Shipdate,
        i.No, i.Order1, i.InvDate 
    FROM Ship S
    FULL JOIN Invoice I
        ON s.No = i.No AND 
          s.Order1=i.Order1
    -- WHERE S.Person = 1
    

    并产生输出

    但是通过在 WHERE 子句中添加以下过滤条件,OUTER JOIN 将产生与 LEFT OUTER JOIN 完全相同的结果

    WHERE S.Person = 1
    

    左连接

    SELECT
        S.No, s.Order1, s.Shipdate,
        i.No, i.Order1, i.InvDate 
    FROM Ship S
    LEFT JOIN Invoice I
        ON s.No = i.No AND 
          s.Order1=i.Order1
    WHERE S.Person = 1
    

    【讨论】:

    【解决方案3】:

    从这个意义上说,完全外连接将给出满足 ON 子句条件(S.[No]=I.[No] AND S.Order1=I.Order1)的所有行,然后给出不满足的所有行ON 子句标准,但确实符合 WHERE 标准。

    因此有必要包括 WHERE I.Person=1 以及 WHERE S.Person=1 但符合 OR 条款的那些尚未发货或已发货但未开票的行(如果有) .

    SELECT S.[No],S.Order1,S.Shipdate,I.No,I.Order1,I.InvDate 
    FROM Ship S FULL OUTER JOIN Invoice I 
    ON S.[No]=I.[No] AND S.Order1=I.Order1 
    WHERE S.Person=1 OR I.Person=1
    

    我假设您只是在寻找第 1 个人的数据。

    【讨论】:

      【解决方案4】:

      您可以使用交叉连接来获得结果。

      代码

      SELECT S.No, s.Order1, s.Shipdate, i.No, i.Order1, i.InvDate 
      FROM Ship S CROSS JOIN
           Invoice I
      WHERE S.Person = 1;
      

      【讨论】:

      • 这行不通有几个原因。首先,WHERE,其次您删除了 OP 的 ON 子句。正如我在问题 cmets 中所讨论的,OUTER JOINCROSS JOIN 完全不同。此外,您可能会考虑将 SQL 格式化为代码。 :)
      • 在交叉连接中,您不需要传递 on Condition,其次,此处需要 where 子句,因为它只会过滤掉结果集中需要的那些记录。
      • 我的意思是 OP 有一个 ON 子句:s.No=i.No AND s.Order1 = i.Order1。这不在您的查询中。
      猜你喜欢
      • 2019-03-08
      • 1970-01-01
      • 2012-01-06
      • 1970-01-01
      • 2011-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多