【问题标题】:Multi table joins - can I add an outer join to this?多表连接 - 我可以添加一个外部连接吗?
【发布时间】:2010-11-11 15:58:21
【问题描述】:

我在从外部联接工作的情况转移到失败的情况时遇到问题。

工作(伪代码示例)

SELECT a.number, a.name, b.ref, c.ref, c.firmref
FROM jobs a, teams b LEFT OUTER JOIN teamfirms c ON b.ref = c.team
WHERE a.ref = b.job

工作和团队之间存在多对一的关系(每个工作多个团队),总是填充

表 c 中可能有也可能没有公司,但上面的查询给出了我期望的结果(大约 5000 条记录)

当我想从第四张桌子中引入有关团队的详细信息时,问题就来了

我正在尝试的代码如下

SELECT a.number, a.name, b.ref, c.ref, c.firmref, d.name
FROM jobs a, teams b LEFT OUTER JOIN teamfirms c ON b.ref = c.team, firms d
WHERE a.ref = b.job
AND d.ref = c.firmref

此时我试图捕获的 NULLS 消失了,我丢弃了大约 500 条记录

我做错了什么?

【问题讨论】:

  • 你永远不应该使用隐式连接。这是一种糟糕的做法,当您需要添加左连接时,会导致意外交叉连接问题和维护问题。并且混合隐式和显式连接是导致错误结果的处方。

标签: sql outer-join


【解决方案1】:

试一试。

select a.number, a.name, b.ref, c.ref, c.firmref, d.name
from jobs a left outer join teams b on b.job = a.ref
left outer join teamfirms c on b.ref = c.team
left outer join firms d on c.firmref = d.ref
left outer join table e on a.column = e.column

或者你可以这样做

select a.number, a.name, b.ref, c.ref, c.firmref, d.name
from
jobs a, teams b, teamfirms c, firms d
where
a.ref = b.job
and b.ref = c.team
and c.firmref = d.ref

一个或另一个......不是两个。

只是为了更好地衡量这个......

您使用 INNER JOIN 返回所有行 从两个表中都有 匹配。 IE。在结果表中 行和列都有值。

LEFT OUTER JOIN 返回所有行 从第一张桌子,即使有 第二个表中没有匹配项。

RIGHT OUTER JOIN 返回所有行 从第二张桌子,即使有 第一个表中没有匹配项。

【讨论】:

  • 这是一种更清晰的书写方式——尽管从问题来看,第一个连接应该是内部连接......但不确定它是否是这样的。
  • 谢谢。我从来没有能够使用比一对表更多的显式联接来解决问题,我认为这可以解决问题!
  • 我认为 Inner 对于第一次连接就足够了,因为两个表之间不应该有任何间隙。
  • 假设以上是正确的,我将如何扩展它以从另一个表 (e) 中获取更多信息,该表 (e) 与表 a 或 b 链接?
【解决方案2】:

您正在混合使用 ANSI 89 和 92 JOIN 语法(隐式和显式 JOIN)。尝试将整个查询转换为显式 JOIN。问题很可能是您要添加的新 JOIN(隐式语法)是 INNER 并且想要成为 OUTER,或者您想以不同的顺序解析 JOIN(一旦将它们全部写为 OUTER,就可以使用括号联接)

【讨论】:

    【解决方案3】:

    试试下面的:

    SELECT 
      a.number, a.name, b.ref, c.ref, c.firmref, d.name 
    FROM 
     jobs a, teams b 
         LEFT OUTER JOIN teamfirms c ON b.ref = c.team
            LEFT OUTER JOIN firms d on c.firmref = d.ref
    WHERE a.ref = b.job 
    

    如果可行,您可以尝试将 2nd LEFT OUTER 变成 INNER。可能是错误的,当我需要这种东西时,我通常将它作为外层。

    【讨论】:

    • 我看到 -1 的驱动器没有任何评论。请告知我们为什么否则我们无法改进我们的答案
    • 是的,对不起,是我,@Larry 解释得很好。
    • @Mr Shoubs:谢谢 - 我确实看到了@Larry 的回答,它也提供了很好的答案,提供了关于原因的理论。它可能只是错过了关于他的请求实际上意味着什么的例子。从外观上看,其他几个人和我几乎同时举了同样的例子。
    【解决方案4】:

    这是我的尝试:

    SELECT a.number, a.name, b.ref, c.ref, c.firmref, d.name 
    FROM jobs a
     join teams b on (b.job = a.ref)
     LEFT OUTER JOIN teamfirms c ON (b.ref = c.team)
     LEFT OUTER JOIN firms d on (d.ref = c.firmref)
    

    这会将所有工作加入团队,如果存在团队公司,则还需要提供公司详细信息。如果没有团队牢固的关系,您仍然会得到空值。

    【讨论】:

      【解决方案5】:

      尝试以下方法:

      SELECT a.number, a.name, b.ref, c.ref, c.firmref, d.name
      FROM jobs a, teams b LEFT OUTER JOIN teamfirms c ON b.ref = c.team
      LEFT OUTER JOIN firms d ON c.firmref = d.ref
      WHERE a.ref = b.job
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-12-08
        • 1970-01-01
        • 1970-01-01
        • 2014-10-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多