【问题标题】:SQL WHERE with LEFT JOIN带有左连接的 SQL WHERE
【发布时间】:2017-02-09 17:21:50
【问题描述】:

表1

ColA       ColB     ColC
A          1        X

表2

ColA     ColB     ColD          ColE
A        1        1/1/2017      No
A        1        1/2/2017      Yes
A        1        1/3/2017      Yes

期望的输出:

A     1      X     1/2/2017

寻找 E = "Yes" 的最早日期。

试过

SELECT Table1.ColA, Table1.ColB, Table1.ColC, min(Table2.ColD) as ColD
FROM Table1
LEFT JOIN Table2
ON Table1.ColA=Table2.ColA AND Table1.ColB=Table2.ColB
WHERE Table2.ColE="Yes"
GROUP BY Table1.ColA, Table1.ColB, Table1.ColC

但我在 Table1 中发现 ColB 为空的记录。该记录未包含在结果中。在这种情况下,ColE 是一个文本字段。

试图找出为什么在此查询中省略了 Table1 中的行 - 想要保持 Table1 完整,只需在适用的情况下添加 Table2 中的列。

【问题讨论】:

  • 你的问题我不清楚,你的数据没有意义。我建议您编辑您的问题以更好地描述数据和format your SQL。此外,将表名和列名更改为比Table1.ColA 稍微抽象一点。也许PeopleBirthdays 之类的。
  • 在您的 SQL 查询中,尝试将 LEFT JOIN 替换为 RIGHT JOIN

标签: sql ms-access


【解决方案1】:

(这被标记为 msaccess,我不完全确定它如何比较 null,所以如果我不在这方面,请有人编辑我。我将使用大多数数据库会做什么nulls,一些快速的谷歌搜索让我认为这是正确的方法。)

正如@wind39 在 cmets 中提到的那样,连接很愚蠢。您在可选(右手)表上有一个 WHERE,因此这实际上变成了内部连接。您的意思是右外连接吗?还是你想要更多这样的东西?

INNER JOIN Table2
ON Table1.ColA=Table2.ColA 
    AND (Table1.ColB=Table2.ColB 
    OR (Table1.ColB is null AND Table2.ColB is null))
WHERE Table2.ColE="Yes"

即给我 Table1 和 Table2 中的所有内容,它们在 ColA 上匹配并且在 ColB 上匹配,除非 Table1.ColB 和 Table2.ColB 都为空。许多数据库不会直接将 Null 等同于自身,这就是为什么有 AND 用于“is null”检查,这可能是您问题的根源。

如果您真的想要 Table1 中的所有内容,但只想要 Table2 中 ColE="Yes" 的那些行,那么您不能使用 WHERE 子句。它将过滤 Table1*Table2 的最终结果,而不仅仅是 Table2 连接上的行。您可以做的一件事是将其移至 LEFT JOIN 子句。

LEFT JOIN Table2
ON Table1.ColA=Table2.ColA 
    AND (Table1.ColB=Table2.ColB 
    OR (Table1.ColB is null AND Table2.ColB is null))
    AND Table2.ColE="Yes"

根据您的数据,可能会有不同的正确解决方案,因为 ColB 为空时的规则在您的问题中并不明显。

【讨论】:

  • 感谢详细的回复,对您有很大帮助!方案 2 完全正确 - 我想要 Table1 中的所有记录。不幸的是(我正在使用 Access),当我添加最后一个语句 Table2.ColE="Yes" 时出现错误。 "不支持 JOIN 表达式"
  • 忽略最后一条评论,在整个表达式周围加上括号修复了错误。它返回了正确的行数 - 看来我在做生意,谢谢!
【解决方案2】:

您的问题“试图找出为什么在此查询中省略 Table1 中的行”的答案仅仅是因为您要同时加入 A 和 B 列。如果 Table1 中的 ColB 为 NULL,则不会将 Table2 中的任何记录与我在您的示例数据中看到的内容进行匹配,因此不会返回该记录。

【讨论】:

  • 如何包含 Table1 中的所有记录?表 1 有 30 万条记录,表 2 有 60 万条记录 - 希望输出有 30 万条记录以及表 2 中的适当附加列。我现在的输出是 9 万条。
  • 您将联接基于 Table1,然后添加引用 Table2 的 WHERE 子句。您不会按原样返回带有 WHERE 子句的 Table1 中的每条记录。您的示例有点抽象,很难说出逻辑到底出了什么问题。如果您可以发布一些实际数据的记录,那么您的逻辑会更容易排列。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-21
  • 2013-11-03
  • 1970-01-01
  • 2017-08-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多