SQL Server-隐式连接与显式连接的不同结果
我的印象是SQL Server-隐式连接与显式连接的不同结果,sql,sql-server,Sql,Sql Server,我的印象是 SELECT * FROM TableA a LEFT JOIN TableB b ON a.ID = b.AID AND b.SomeString <> 'ABC' 选择* 从表a 左连接a.ID=b.AID和b.SomeString'ABC'上的表b 及 选择* 从表a a.ID=b.AID上的左联接表b 其中b.AID为NULL或b.SomeString“ABC” 也会产生同样的结果 不幸的是,在我的情况下,它们不是:-( 它们可能不存在的原因是什么?因为空逻
SELECT *
FROM TableA a
LEFT JOIN TableB b ON a.ID = b.AID AND b.SomeString <> 'ABC'
选择*
从表a
左连接a.ID=b.AID和b.SomeString'ABC'上的表b
及
选择*
从表a
a.ID=b.AID上的左联接表b
其中b.AID为NULL或b.SomeString“ABC”
也会产生同样的结果
不幸的是,在我的情况下,它们不是:-(
它们可能不存在的原因是什么?因为空逻辑
在第一个查询中,您得到A中的所有行,只有当键匹配和B时,才会在B上联接。如果B.SomeString不等于ABC。如果B.SomeString为null,就像找不到键一样,您得到
…并且null不等于ABC
。根据null比较规则,将null与任何“失败”进行比较,例如,NULL'ABC'
等同于false.Net结果:如果找不到ID,则b.SomeString为NULL,并且从返回的集合中丢弃该行
在第二个查询中,您得到A中的所有行,只有在键匹配的情况下才在B上连接,表连接后才计算where子句。它(本质上)表示保留ID不匹配的行或B.SomeString“ABC”(如上所述,它将排除null)。因此,您将得到ID不匹配的行,和与b.SomeSting不匹配的行
这些东西可能很难理解,很难解释,没有样本数据也很难解释——我的意思是,你应该在你的查询中找出答案,直到你明白这是如何工作的。表A
+----+
| ID |
+----+
| 1 |
| 2 |
| 3 |
+----+
表B
+-----+-----------------+
| AID | SomeString |
+-----+-----------------+
| 1 | SomeOtherString |
| 2 | ABC |
+-----+-----------------+
问题1 问题1.5 这稍微改变了语义,因为现在只需要满足
id
谓词的匹配,而不需要满足字符串条件。在这个新的匹配条件下,id为2和3的a中的行与B中的行匹配,只有id=3被外部联接添加回
+----+------+-----------------+
| ID | AID | SomeString |
+----+------+-----------------+
| 1 | 1 | SomeOtherString |
| 2 | 2 | ABC |
| 3 | NULL | NULL |
+----+------+-----------------+
问题2
因为它们是不同的查询。我同意这些评论。我只是想尝试详细解释一下。“如果b.SomeString为null,就像找不到键一样,则会得到……并且null不等于ABC……并且从返回集丢弃该行。”这整个部分都是错误的。外部联接中的不匹配行将被保留,并在计算匹配后进行null扩展。哇,感谢您的时间和出色的回答!!!真不敢相信我在读这篇文章之前是多么愚蠢:-D抱歉,哈哈
SELECT *
FROM TableA a
LEFT JOIN TableB b
ON a.ID = b.AID
AND b.SomeString <> 'ABC'
+----+------+-----------------+
| ID | AID | SomeString |
+----+------+-----------------+
| 1 | 1 | SomeOtherString |
| 2 | NULL | NULL |
| 3 | NULL | NULL |
+----+------+-----------------+
SELECT *
FROM TableA a
LEFT JOIN TableB b ON a.ID = b.AID
+----+------+-----------------+
| ID | AID | SomeString |
+----+------+-----------------+
| 1 | 1 | SomeOtherString |
| 2 | 2 | ABC |
| 3 | NULL | NULL |
+----+------+-----------------+
SELECT *
FROM TableA a
LEFT JOIN TableB b
ON a.ID = b.AID
WHERE b.AID IS NULL
OR b.SomeString <> 'ABC'
+----+------+-----------------+
| ID | AID | SomeString |
+----+------+-----------------+
| 1 | 1 | SomeOtherString |
| 3 | NULL | NULL |
+----+------+-----------------+