【问题标题】:SQL outer Join 3 tables merging dataSQL外连接3表合并数据
【发布时间】:2014-03-18 16:25:34
【问题描述】:

我想将 3 个表连接在一起,让它返回一个结果为空的数据。

tblCustomer 是始终具有所需结果的主表。然后它将绑定到另外 2 个表 tblEvents 和 tblPending,并应返回其中任何一个的数据。

例子

tblCustomer.CustomerID       tblEvents.EventID      tblPending.PendingID
1                            50                     NULL
1                            51                     NULL
2                            NULL                   30
2                            70                     NULL
2                            NULL                   90

我试过像这样外部连接表格:

dbo.tblEvents 
LEFT OUTER JOIN dbo.tblCustomer 
  ON dbo.tblEvents.CustomerID = dbo.tblCustomer.CustomerID 
LEFT OUTER JOIN dbo.tblPending 
  ON dbo.tblCustomer.CustomerID = dbo.tblPending.CustomerID

但它给了我这样的结果:

  CustomerID     EventID      PendingID
  2              70           30
  2              70           90

是否有一种简单的方法可以使其连接到客户表但不尝试连接到附加表。 IE Pending 和 Event 之间没有任何关系,只是它们都与 Customer 相关。

【问题讨论】:

  • 您将其标记为 mysql 和 sqlserver。您真的需要两者的解决方案吗?
  • 对不起,你是对的。我已经删除了 mysql 标签。我正在使用 Microsoft SQL Server 2013。
  • 没有 SQL Server 2013 这样的东西。现在还没有出来的是 ether 2012 或 2014。

标签: sql sql-server join


【解决方案1】:

如果您只想要一个事件或待处理,您可能想要两个联接的联合,例如

SELECT tblCustomer.CustomerID, tblEvents.EventID, null AS tblPending.PendingID FROM dbo.tblCustomer LEFT OUTER JOIN dbo.tblEvents ON dbo.tblEvents.CustomerID = dbo.tblCustomer.CustomerID 
UNION
SELECT tblCustomer.CustomerID, null AS tblEvents.EventID, tblPending.PendingID FROM dbo.tblCustomer LEFT OUTER JOIN dbo.tblPending ON dbo.tblCustomer.CustomerID = dbo.tblPending.CustomerID

【讨论】:

  • 谢谢。运行 2 个 select 语句并使用 Union 效果很好。
【解决方案2】:

这会从事件中获取空值和/或从 sql server 中获取挂起

select customerid, eventid, pendingid 
from tblcustomer c
left join tblevents e
on c.customerid = e.customerid
left join tblPending p
on c.customerid = p.customerid

您可以添加 where 子句以仅获取未决为空的值...

... where p.pendingid is null

或者事件为空的地方

... where e.eventsid is null

【讨论】:

    【解决方案3】:

    你想要的是一个FULL OUTER JOIN,它在mysql中不存在,所以你必须做你的左外连接和右外连接联合

    LEFT OUTER JOIN dbo.tblCustomer ON dbo.tblEvents.CustomerID = dbo.tblCustomer.CustomerID 
    LEFT OUTER JOIN dbo.tblPending ON dbo.tblCustomer.CustomerID = dbo.tblPending.CustomerID 
    UNION
    RIGHT OUTER JOIN dbo.tblCustomer ON dbo.tblEvents.CustomerID = dbo.tblCustomer.CustomerID 
    RIGHT OUTER JOIN dbo.tblPending ON dbo.tblCustomer.CustomerID = dbo.tblPending.CustomerID 
    

    在此之后,表格应该以正确的顺序组合,您可以通过不为 null 或特定 id 的字段过滤掉

    【讨论】:

      【解决方案4】:
      dbo.tblEvents  
          INNER JOIN dbo.tblCustomer 
        ON dbo.tblEvents.CustomerID = dbo.tblCustomer.CustomerID 
          INNER JOIN dbo.tblPending 
        ON dbo.tblCustomer.CustomerID = dbo.tblPending.CustomerID
         where (tblEvents.EventID is null) or (tblPending.PendingID is null)
      

      【讨论】:

        【解决方案5】:
        dbo.tblEvents LEFT OUTER JOIN 
        dbo.tblCustomer ON 
        dbo.tblEvents.CustomerID  = dbo.tblCustomer.CustomerID
        

        ...表示您希望将所有内容保留在 tblEvents 中,并且只保留那些相同的 tblCustomer 。您真的希望 tblCustomer 保留所有内容。

        所以正确的 SQL 应该是:

        dbo.tblEvents RIGHT OUTER JOIN
        dbo.tblCustomer ON dbo.tblEvents.CustomerID = dbo.tblCustomer.CustomerID LEFT OUTER JOIN
        dbo.tblPending ON dbo.tblCustomer.CustomerID = dbo.tblPending.CustomerID
        

        我个人喜欢从主表(客户)开始,一切都源于此;它合乎逻辑且易于阅读。

        dbo.tblCustomer LEFT OUTER JOIN
        dbo.tblEvents ON dbo.tblCustomer.CustomerID = dbo.tblEvents.CustomerID LEFT OUTER JOIN
        dbo.tblPending ON dbo.tblCustomer.CustomerID = dbo.tblPending.CustomerID
        

        要从 Events 或 Pending 中仅选择具有 null 的那些,请将 where 子句添加到末尾:

        WHERE dbo.tblEvents.CustomerID Is Null or dbo.tblPending.CustomerID Is Null
        

        【讨论】:

          【解决方案6】:

          您的问题来自于在FROM 子句中选择了错误的表。由于您总是希望显示客户记录,但只有 EVENTPENDING(如果它们存在),因此您需要使用 CUSTOMER 开始查询并使用 LEFT OUTER JOIN 包括其他两个,这意味着将检索来自客户的所有数据 + 记录每个表中的匹配项。

          SELECT c.CustomerId
                 ,e.EventID
                 ,p.PendingID
              FROM dbo.tblCustomer AS c
              LEFT OUTER JOIN dbo.tblEvents AS e
                  ON c.CustomerID = e.CustomerID
              LEFT OUTER JOIN dbo.tblPending AS p
                  ON c.CustomerID = p.CustomerID
          

          另一个建议是使用ALIAS,在我的代码中我有as c,这让我可以将tblCustomer 称为c,而不是再次指定整个表。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2018-03-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-10-30
            • 1970-01-01
            相关资源
            最近更新 更多