这种代码中的'Select 0 from'是什么意思?

6
“有人能帮助我理解‘Select 0 from’的意思吗?”
delete from table1
    where cond1 and cond2 and cond3
        and not exists
        ( select 0  from table2 where cond1 and cond2 )

我尝试查看一些关于此事的SO线程,但在短时间内理解起来有点太复杂了,涉及到优化等方面。这里有没有简单的解释可以说明正在发生什么?

1
你可以用任何你想要的值(NULL, 1, 56456456, Foo, Column1)来替换0,这并不重要且会被忽略,在SQL-Server中实际上没有任何数据被返回。 - Tim Schmelter
5个回答

11

SELECT 0 FROM table 并不返回 table 表的任何列值,而是对于 table 表中的每一行返回一个常量 - 例如,如果您有以下表格:

TABLE
id | name   | age
0  | John   | 12
1  | Jack   | 22
2  | Martin | 42

以下是相关陈述:

SELECT 0 FROM table WHERE age > 12

这将导致:
0
0

因为只有年龄为22岁和42岁(分别为IDS 1和2)的两行数据的年龄大于12岁。


这是个好例子!我本来想问如果我们在子查询中把'0'替换成count(),那么会不会返回COUNT()次数的0。所以我猜确实是这样的。谢谢。 - Somjit
为什么选择0有用?我的意思是,既然我们可以使用count来了解行数,那么它的目的是什么? - jkonst
4
有时候在使用'EXISTS'语句的时候,与其用'COUNT()'函数不如使用'SELECT 0'语句,这样可以提高SQL Server的性能。例如:'IF EXISTS ( SELECT 0 FROM Deleted )'会在找到第一行记录后立即停止查询并返回真值(此时会返回'0')。 - Kr15

3
这句话的惯用语SQL是:
delete from table1
where cond1 and cond2 and cond3
    and not exists
    ( select *  from table2 where cond1 and cond2 )

需要关注的重要关键词是 exists。因此,如果cond1cond2cond3都为真,并且table2中没有行满足(inner) cond1 cond2为真,则此查询将从table1中删除行。

某些数据库产品(特别是早期版本的SQL Server,我认为是2000年之前的版本)实际上在给定exists (select * ...形式时会执行更多的工作,因此成为常规做法是替换为常量值(01),以便它不必费力地检索任何实际数据。正如我所说,我们只是检查是否存在行,不关心它们的内容。

在您使用的任何版本的SQL Server中,exists (select * ...都可以,优化器可以理解它。其他数据库产品可能会对这种形式产生问题。


2

exists 用于检查以下子查询是否返回结果,这意味着连接至少有一个链接(如果子查询正在连接,则不清楚在您的伪代码中)。

子查询返回什么是完全无关紧要的。在此情况下,它为 0


一个简短的例子会很有帮助。如果子查询返回的内容与外部查询无关,我很难理解子查询的重要性。 - Somjit
1
如果子查询中的条件为“true”,则返回一个或多个记录。如果它们为“false”,则不返回任何记录。甚至没有一个。exists检查是否返回了至少一条记录。但是,exists并不在意返回的记录是否包含像01hello这样的内容。它只检查是否存在某些东西 - juergen d
1
基本上就像是一个布尔条件检查...不关心返回多少东西,只要告诉我是否有返回。如果有返回,NOT EXISTS 将 true 转换为 false,这将使整个外部 WHERE 子句的结果为 'false',因此,没有任何内容被删除! - Somjit

2
如果子查询返回1个或多个行,则不会执行DELETE操作。

1
感谢您提供简单的答案。 - Somjit

1
实际上,根据您的查询,SELECT 0 只验证 WHERE 子句中的条件。因此,如果条件为真,则子查询将返回 0
然后,NOT EXISTS 将检查您的子查询是否返回值。换句话说,如果子查询中设置的条件不存在,则将执行 DELETE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接