【问题标题】:Return rows even if record does not exist LEFT OUTER JOIN即使记录不存在也返回行 LEFT OUTER JOIN
【发布时间】:2011-08-20 07:31:52
【问题描述】:

我在下面有 2 张桌子:

Table_1
[Group No] [Test No] [Description]
123        1         [First Test]
123        2         [Second Test]
123        3         [Third Test]

Table_2
[Sample No] [Test No] [Result Description]
ABC         1         [Some More Result]
ABC         3         [Some Result]
DEF         1         [A Result]
DEF         2         [Results More]
DEF         3         [Bad Results]

这是我的查询:

SELECT Table_1.[Group No], Table_1.[Test No], Table_1.Description, Table_2.[Result Description]
FROM Table_1 
LEFT OUTER JOIN Table_2 ON Table_1.[Test No] = Table_2.[Test No]
WHERE (Table_1.[Group No] = '123') AND (Table_2.[Sample No] = 'ABC')

djacobson 的询问:

SELECT Table_1.[Group No], Table_1.[Test No], Table_1.Description, Table_2.[Result Description]
FROM Table_1 
LEFT OUTER JOIN Table_2 ON Table_1.[Test No] = Table_2.[Test No]
WHERE (Table_1.[Group No] = '123') 
  AND (Table_2.[Sample No] IS NULL OR Table_2.[Sample No] = 'ABC')

这会返回:

[Group No] [Test No] [Description] [Result Description]
123        1         [First Test]  [Some More Result]
123        3         [Third Test]  [Some Result]

但我真正想要的是:

[Group No] [Test No] [Description] [Result Description]
123        1         [First Test]  [Some More Result]
123        2         [Second Test] NULL
123        3         [Third Test]  [Some Result]

这可能吗?我想返回Test No 2的记录。但是,我如何加入一个不存在的记录?或者这根本不可能?有哪些替代方案?

【问题讨论】:

    标签: sql-server left-join


    【解决方案1】:

    尽管正确使用了外连接,但通过在 WHERE 子句中包含该表中的列,您将结果集限制为 Table_2 中存在值的情况。如果您想要样本编号为 ABC 的记录,或者 Table_2 中没有记录,您需要这样做:

    SELECT Table_1.[Group No], Table_1.[Test No], Table_1.Description, Table_2.[Result Description]
    FROM Table_1 
    LEFT OUTER JOIN Table_2 ON Table_1.[Test No] = Table_2.[Test No]
    WHERE (Table_1.[Group No] = '123') 
      AND (Table_2.[Sample No] IS NULL OR Table_2.[Sample No] = 'ABC')
    

    或者,您可以在加入 Table_2 时过滤结果(在这种情况下,读取更清晰):

    SELECT Table_1.[Group No], Table_1.[Test No], Table_1.Description, Table_2.[Result Description]
    FROM Table_1 
    LEFT OUTER JOIN Table_2 ON Table_1.[Test No] = Table_2.[Test No] AND Table_2.[Sample No] = 'ABC'
    WHERE (Table_1.[Group No] = '123') 
    

    这应该完成同样的事情。这里重要的一点是 WHERE 子句过滤加入表的结果。如果您正在使用外连接但想要对外连接表进行过滤,则必须处理连接远端不存在记录的情况。

    【讨论】:

    • 嗨 djacobson,这仍然产生相同的结果,我仍然没有得到测试 2 的行。它与 JOIN 有关吗?
    • 这很奇怪...您现在使用的是什么查询?请编辑您的问题以包含它(您可以在问题中使用源代码格式,但不能在评论中使用)。
    • 嗨 djacobson,第二个查询似乎产生了所需的结果。我已经编辑了我的原始问题,包括您建议的第一个查询 - 这不起作用,但第二个有效。
    • 啊,我测试了这个,明白了为什么第一个查询排除了测试 2:因为它在加入时没有过滤 Table_2,所以我们得到了测试 2 加入样本 DEF 的记录。然后我们过滤那些包含 no 样本或使用样本 ABC 的结果,以便排除测试 2 的记录。 (查看正在发生的事情的最简单方法是从没有 WHERE 子句的连接表中执行 SELECT *)。所以在我们加入的时候过滤Table_2,然后在加入后过滤Group,是要走的路!
    • 谢谢,这就是答案!我应该记住,WHERE 子句中的过滤会限制视图,我应该在 FROM 子句中进行过滤,对吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-29
    • 2023-02-10
    • 2017-09-02
    • 2015-12-21
    • 1970-01-01
    • 2018-08-04
    • 1970-01-01
    相关资源
    最近更新 更多