【问题标题】:Query with Left Outer Join使用左外连接查询
【发布时间】:2013-11-12 16:45:51
【问题描述】:

我无法弄清楚这一点。

根据 Jeff Atwood A Visual Explanation of SQL Joins 的说法,左外连接从表 A 中生成一组完整的记录,匹配​​的记录(如果可用)在表 B 中。如果没有匹配项,则右侧将包含 null。

左表 (TableA) 没有重复项。右表 B 有每个客户编号的 1 或 2 个条目。 PrimaryTP 用 1 指定一个为主,另一个用 0 指定。

我不应该包含 And B.PrimaryTP = 1 行,因为 TableA 没有重复项。然而,如果我把它遗漏掉,我会得到重复的客户号码。为什么?

你能帮我理解它是如何工作的吗?这让我很困惑。 And B.PrimaryTP = 1 的逻辑让我无法理解。然而它似乎工作。尽管如此,如果我不理解它,我还是害怕相信它。你能帮我理解一下吗。还是我在查询中隐藏了逻辑错误?

SELECT A.ClientNum --returns a list with no duplicate client numbers
FROM (...<TableA>
) as A

Left Outer Join

<TableB> as B
on A.ClientNum = B.ClientNum

--eliminate mismatch of (ClientNum <> FolderNum)
Where A.ClientNum Not In
(
    Select ClientNum From <TableB>
    Where ClientNum Is Not Null
    And ClientNum <> IsNull(FolderNum, '')
)

--eliminate case where B.PrimaryTP <> 1
And B.PrimaryTP = 1 

【问题讨论】:

  • 哇!感谢所有的帮助。现在,正确的多个记录如何导致重复是有道理的。谢谢。

标签: sql-server tsql


【解决方案1】:

INNER JOINLEFT JOIN 的区别只是LEFT JOIN 在表 B 中没有对应行的情况下仍然返回表 A 中的行。

但它仍然是JOIN,也就是说如果表B中有多个对应的行,它会将表A中的行加入到每个表中

因此,如果您想确保在表 A 中的每一行中得到的结果不超过一个,则必须确保从表 B 中找到的结果不超过一个 - 因此是 And B.PrimaryTP = 1

【讨论】:

    【解决方案2】:

    如果您在 A 中有一个客户编号,在表 B 中有两个匹配,那么您将得到重复。

    假设你有以下数据,

    Table-A(client Num) Table-B(client Num)
    1          2
    2          2
    
    The left Join Results
    
    Table-A(client Num) Table-B(client Num)
    1                       (null)
    2                       2
    2                       2
    

    这是重复的原因。因此,您需要从表 B 中获取不同的值或对结果集执行 Distinct。

    【讨论】:

      【解决方案3】:

      我不应该包含 And B.PrimaryTP = 1 行,因为 TableA 没有重复项。然而,如果我把它遗漏掉,我会得到重复的客户号码。为什么?

      因为右表中的两行都匹配左表中的一行。 SQL Server 无法输出三角结果;它必须为每个连接的行显示两个表中的列。对于 INNER JOIN 也是如此。

      DECLARE @a TABLE(a INT);
      DECLARE @b TABLE(b INT);
      
      INSERT @a VALUES(1),(2);
      INSERT @b VALUES(1),(1);
      
      SELECT a.a, b.b FROM @a AS a 
      LEFT OUTER JOIN @b AS b ON a.a = b.b;
      
      SELECT a.a, b.b FROM @a AS a 
      INNER JOIN @b AS b ON a.a = b.b;
      

      结果:

      a   b
      --  ----
      1   1
      1   1
      2   NULL
      
      a   b
      --  --
      1   1
      1   1
      

      【讨论】:

        【解决方案4】:

        在你给连接的链接上解释得很好。所以问题是您有来自表 A 的几条记录(无论是否有重复),对于 A 中的 1 条记录,B 中有 2 条记录(在某些情况下)。为避免这种情况,您可以使用DISTINCT 子句或GROUP BY 子句。

        【讨论】:

          【解决方案5】:

          LEFT OUTER JOIN 将为您提供来自A 的所有记录,所有来自B 的匹配记录。与 INNER JOIN 的区别在于,如果 B 中没有 no 匹配记录,INNER 连接将完全忽略 A 中的记录,而 LEFT 连接仍将包含一行来自A 的结果。

          但是,在您的情况下,您可能还想查看 DISTINCT 关键字。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多