Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL Server-隐式连接与显式连接的不同结果_Sql_Sql Server - Fatal编程技术网

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            |
+----+------+-----------------+