使用左外连接查询

时间:2013-11-12 16:45:52

标签: sql-server tsql

我无法搞清楚这一点。

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

左表(TableA)没有重复项。右表B对每个客户编号有1或2个条目。 PrimaryTP将一个指定为primary,另一个指定为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 

5 个答案:

答案 0 :(得分:1)

INNER JOINLEFT JOIN之间的区别仅在于,当表B中没有相应的行时,LEFT JOIN仍会返回表A中的行。

但它仍然是JOIN,这意味着如果表B中有多个相应的行,它会将表A中的行连接到其中的每一行。< / p>

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

答案 1 :(得分:1)

如果您在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中获取不同的值,或对结果集执行“区别”。

答案 2 :(得分:1)

  

我不应该包含该行和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

答案 3 :(得分:1)

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

答案 4 :(得分:0)

LEFT OUTER JOIN将为A提供所有来自B的匹配记录的所有记录。与INNER JOIN的区别在于,如果B中存在 no 匹配记录,则INNER联接将完全省略A中的记录,而LEFT联接然后,仍会包含一行,其中包含A的结果。

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