有没有一种方法可以在SQL中将EXCEPT语句重写为NOT IN语句



我刚开始学习SQL几周,刚刚完成了一项关于使用IN和NOT IN的家庭作业。我设法得到了正确的答案,但我使用了EXCEPT子句,我们还不允许使用它。据我所知,EXCEPT和NOT IN在SQL中是非常相似的语句,但我不明白区别是什么

SELECT *
FROM table
WHERE x IN (
SELECT x
/* ... some subquery*/
EXCEPT
SELECT x
/* ... some other subquery*/ 
)

有没有一种方法可以在不使用EXCEPT语句的情况下重写这个通用查询?EXCEPT和NOT IN通常有什么不同?

编辑:另一篇帖子似乎有一些好的信息,但它似乎专注于EXISTS而不是IN,它们有不同的目的,不是吗?

这可能有助于您理解Except和NOT IN之间的区别

EXCEPT运算符返回左侧表中不存在的所有不同行。

另一方面,"NOT IN"将返回左侧表中不存在于右侧表中的所有行,但不会从结果中删除重复的行。

SQL是一种声明性语言。因此,有许多构造可以转换为相同的关系代数树/执行计划。例如,可以使用inner join或CROSS join+WHERE或、+WHERE或LEFT/RIGHT join+WHERE指定内部联接。

EXCEPT/INTERSECT是集合运算符,IN/NOTIN是谓词。以为例

SELECT *
FROM table
WHERE x IN (
SELECT x
/* ... some subquery*/
EXCEPT
SELECT x
/* ... some other subquery*/ 
)

这可以像一样使用IN/NOT-IN写入

SELECT *
FROM table as t1
WHERE t1.x IN (
SELECT t2.x
FROM t2
WHERE t2.x NOT IN (
SELECT t3.x
FROM t3
)
)

现在,在语法方面,这些意思是相同的,但在语义上,它们可能不会产生相同的结果。例如,如果列X可以为null,那么NOT IN将产生不同的结果。

最后,对于这个简单的例子,如果您在SQLServerManagementStudio中查看这两个查询的执行计划,您会发现它们使用了类似的计划/联接策略。这是因为SQL Server会将语法转换为关系树,该关系树经过优化以生成执行计划。在这个翻译之后,对于不同的查询,最终计划可能是相同的。

最新更新