Tsql 加入vs.加入vs.存在vs.存在

Tsql 加入vs.加入vs.存在vs.存在,tsql,exists,notin,Tsql,Exists,Notin,我读了一篇文章,解释了join和in以及exists子句之间的区别,但我对使用NOT in和NOT exists子句时不同结果的解释感到困惑。有人能澄清为什么NOT EXISTS子句和NOT IN子句的输出之间存在差异吗?在从表t2中删除空行(t2.id=8)之后,我尝试了删除,但仍然得到了相同的结果 以下是本文中的SQL脚本: CREATE TABLE t1 (id INT, title VARCHAR(20), someIntCol INT) GO CREATE TABLE t2 (id I

我读了一篇文章,解释了join和in以及exists子句之间的区别,但我对使用NOT in和NOT exists子句时不同结果的解释感到困惑。有人能澄清为什么NOT EXISTS子句和NOT IN子句的输出之间存在差异吗?在从表t2中删除空行(t2.id=8)之后,我尝试了删除,但仍然得到了相同的结果

以下是本文中的SQL脚本:

CREATE TABLE t1 (id INT, title VARCHAR(20), someIntCol INT)
GO
CREATE TABLE t2 (id INT, t1Id INT, someData VARCHAR(20))
GO

INSERT INTO t1
SELECT 1, 'title 1', 5 UNION ALL
SELECT 2, 'title 2', 5 UNION ALL
SELECT 3, 'title 3', 5 UNION ALL
SELECT 4, 'title 4', 5 UNION ALL
SELECT null, 'title 5', 5 UNION ALL
SELECT null, 'title 6', 5

INSERT INTO t2
SELECT 1, 1, 'data 1' UNION ALL
SELECT 2, 1, 'data 2' UNION ALL
SELECT 3, 2, 'data 3' UNION ALL
SELECT 4, 3, 'data 4' UNION ALL
SELECT 5, 3, 'data 5' UNION ALL
SELECT 6, 3, 'data 6' UNION ALL
SELECT 7, 4, 'data 7' UNION ALL
SELECT 8, null, 'data 8' UNION ALL
SELECT 9, 6, 'data 9' UNION ALL
SELECT 10, 6, 'data 10' UNION ALL
SELECT 11, 8, 'data 11'
下面是SQL查询及其解释:

--在中没有得到正确的结果。 --这是因为IN如何处理null和三值逻辑 --NULL被视为未知,因此如果t2.t1id中存在NULL --NOT IN将返回NOT TRUE或NOT UNKNOWN。两者都不可能是真的。 --当t2表的t1id列中有NULL时,NOT in查询将始终返回一个空集

SELECT    t1.* 
FROM    t1 
WHERE    t1.id NOT IN (SELECT t1id FROM t2)
--“不存在”将获得正确的结果

SELECT    t1.* 
FROM    t1 
WHERE    NOT EXISTS (SELECT * FROM t2 WHERE t1.id = t2.t1id)
GO

DROP TABLE t2
DROP TABLE t1
以下是文章的链接:

CREATE TABLE t1 (id INT, title VARCHAR(20), someIntCol INT)
GO
CREATE TABLE t2 (id INT, t1Id INT, someData VARCHAR(20))
GO

INSERT INTO t1
SELECT 1, 'title 1', 5 UNION ALL
SELECT 2, 'title 2', 5 UNION ALL
SELECT 3, 'title 3', 5 UNION ALL
SELECT 4, 'title 4', 5 UNION ALL
SELECT null, 'title 5', 5 UNION ALL
SELECT null, 'title 6', 5

INSERT INTO t2
SELECT 1, 1, 'data 1' UNION ALL
SELECT 2, 1, 'data 2' UNION ALL
SELECT 3, 2, 'data 3' UNION ALL
SELECT 4, 3, 'data 4' UNION ALL
SELECT 5, 3, 'data 5' UNION ALL
SELECT 6, 3, 'data 6' UNION ALL
SELECT 7, 4, 'data 7' UNION ALL
SELECT 8, null, 'data 8' UNION ALL
SELECT 9, 6, 'data 9' UNION ALL
SELECT 10, 6, 'data 10' UNION ALL
SELECT 11, 8, 'data 11'

谢谢大家!

正如我所看到的,在很多情况下,你可以将它们作为同一件事来使用,但你不能忘记它们背后的细节

应用
NOT IN
NOT EXISTS
可能会得到相同的结果,但您可以看到查询中涉及
NULL
值的差异。因为
不存在
是获取具有
NULL值的行的唯一方法

在本例中,您可以更好地看到:

update cars set c_owner = NULL where c_id = BMW03444
嗯。。。让我们试着看看有没有还没有卖出的车

select count(*) from cars where c_owner not it (select c_name from customers);
输出:

计数(*):0

失败在哪里?很简单。您并不是在申请一组买家未包括在列表中的汽车。你只是想要一辆没有主人的车。任何人,即使他不在名单上。正确的形式是:

select count(*) 
from cars c1 
where not exists (
  select c_owner 
  from customers c2
  where c1.c_owner=c2.customer_id
);
计数(*):1

这是因为
不在
需要特定值才能签入。因此,
NULL
值被设置为
FALSE
且不计数。
NOT EXISTS
检查集合中元素的不存在性,因此
NULL
值被设置为TRUE并包含在内。

这里有一篇更好的文章:除此之外,你的问题是什么?@TimSchmelter“有人能澄清为什么NOT EXISTS子句和NOT in子句的输出之间存在差异吗?”@乔克:但他后来自己加了一个解释,这让人困惑。他可能想确认他的解释是否属实。我已经加上了文章中的解释。不过,我不太清楚这意味着什么。我一直在寻求对这一解释的澄清。