【问题标题】:I cannot get this LEFT JOIN to work (I don't understand joins)我无法让这个 LEFT JOIN 工作(我不明白连接)
【发布时间】:2015-12-04 21:45:15
【问题描述】:

这些查询都得到结果:

SELECT * FROM Table1 WHERE Criteria = '5'
SELECT * FROM Table1 WHERE Criteria = '3'

这个查询得到结果:

SELECT *
FROM Table1 p, Table2 m
WHERE p.UID = m.ID
AND Criteria = '5'

这个查询没有:

SELECT *
FROM Table1 p, Table2 m
WHERE p.UID = m.ID
AND Criteria = '3'

我正在尝试将这些转换为正确的连接,即使正确的表中没有记录,它也会返回结果。

我已经尝试了以下

SELECT *
FROM Table1 p LEFT JOIN Table2 m ON p.UID = m.ID
WHERE p.Criteria = '3'
AND m.OtherCriteria = 'Moron'
--0 results

我有限的理解是左连接是我需要的。我想要 left 表中的数据,即使 right 表中没有匹配的数据。由于这不起作用,我还尝试了right joinleft outer joinright outer joinfull join。没有返回结果。

我错过了什么?

【问题讨论】:

  • 你说它看起来对吗?可能是Caché... :(
  • 从您的第一次观察 (SELECT * FROM Table1 WHERE Criteria = '3') 中,您的 LEFT JOIN 为何“不起作用”已经很清楚了。
  • 请赐教?
  • 在这种情况下,尝试将 LEFT JOIN 理解为一组可选的列(来自表 2 的列)附加到主列集(来自表 1)。在某种意义上是可选的,如果它们不存在,它们将不会抑制任何行。但是,如果主查询(来自 Table1)已经没有行,那么什么都不做。
  • @rslemos 再次阅读了他的帖子,并在您的理解中包含了第一行——他说SELECT * FROM Table1 WHERE Criteria = '3' 返回行

标签: sql join intersystems-cache


【解决方案1】:

评论太长了。您的查询:

SELECT *
FROM Table1 p LEFT JOIN
     Table2 m
     ON p.UID = m.ID AND p.Criteria = '3';

应该为table1 中的所有行返回一行。如果没有匹配,则值将是 NULL 对应于 table2。这很容易证明:Here 是 SQL Fiddle 上的 MySQL 示例。因为这是标准行为,所以它应该适用于几乎任何数据库。

请注意,此查询与此查询完全不同:

SELECT *
FROM Table1 p LEFT JOIN
     Table2 m
     ON p.UID = m.ID 
WHERE p.Criteria = '3';

此查询不返回任何行,因为没有行匹配 WHERE 子句。过滤发生在(概念上)LEFT JOIN之后。

我稍微更改了 SQL Fiddle 中的代码,所以查询是:

select *
from (select 5 as criteria, 1 as id union all
      select 6, 1 union all
      select 7, 2
     ) table1 left join
     (select 1 as id, 'x' as x
     ) table2
     on table1.id = table2.id and criteria = 3;

注意:您应该始终使用明确的join 语法。简单规则:不要在FROM 子句中使用逗号。

如果您的数据库没有返回任何行,那么它的行为方式不标准,或者您的界面出于某种原因决定过滤这些行。

【讨论】:

  • 这就是我想要做的。让我试着澄清我的问题,对不起。
  • 好的,我更新了。抱歉,开始时令人困惑,希望现在更好。
  • 他说没有连接的 p.Criteria = '3' 确实返回行,所以如果他使用 where 对他的问题(或不应该)无关紧要。
  • @ScottBeeson 。 . .虽然重点不同,但解释仍然准确。为什么on 子句返回非真并不重要。第一个表中的所有行仍应返回。结论保持不变:缓存没有实现LEFT JOIN 的标准行为。
  • 我同意,唯一的解释是一个错字,这里显示的 OP 实际上不是运行的。这种差异是问题的根源。
猜你喜欢
  • 2011-03-28
  • 1970-01-01
  • 2018-11-28
  • 1970-01-01
  • 1970-01-01
  • 2014-06-18
  • 2011-09-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多