SQL Exists函数使用方法说明

作者:袖梨 2022-06-29

EXISTS(包括 NOT EXISTS )子句的返回值是一个BOOL值。 EXISTS内部有一个子查询语句(SELECT ... FROM...), 我将其称为EXIST的内查询语句。其内查询语句返回一个结果集。 EXISTS子句根据其内查询语句的结果集空或者非空,返回一个布尔值。

一种通俗的可以理解为:将外查询表的每一行,代入内查询作为检验,如果内查询返回的结果取非空值,则EXISTS子句返回TRUE,这一行行可作为外查询的结果行,否则不能作为结果。
 

Exists是子查询的一种条件形式,通过判断Exists的选择表达式(括号内的部分)的结果,如果存在一行或多行结果记录,则Exists整个子查询结果为真,否则为假。由于我们采用Exists来实现子查询,只需要关心是否存在满足条件的记录,所以选择表达式的选择列表采用*来实现,当然,你也可以在选择列表指明具体的某些列,但这些列将在整个搜索过程中被忽略。

语法

EXISTS subquery
参数
subquery

是一个受限的 SELECT 语句 (不允许有 COMPUTE 子句和 INTO 关键字)。有关更多信息,请参见 SELECT 中有关子查询的讨论。
结果类型

Boolean
结果值

如果子查询包含行,则返回 TRUE。
示例
A. 在子查询中使用 NULL 仍然返回结果集

这个例子在子查询中指定 NULL,并返回结果集,通过使用 EXISTS 仍取值为 TRUE。

 代码如下 复制代码

USE Northwind
GO
SELECT CategoryName
FROM Categories
WHERE EXISTS (SELECT NULL)
ORDER BY CategoryName ASC
GO

B. 比较使用 EXISTS 和 IN 的查询

这个例子比较了两个语义类似的查询。第一个查询使用 EXISTS 而第二个查询使用 IN。注意两个查询返回相同的信息。

 代码如下 复制代码

USE pubs
GO
SELECT DISTINCT pub_name
FROM publishers
WHERE EXISTS
   (SELECT *
   FROM titles
   WHERE pub_id = publishers.pub_id
   AND type = 'business')
GO

-- Or, using the IN clause:

USE pubs
GO
SELECT distinct pub_name
FROM publishers
WHERE pub_id IN
   (SELECT pub_id
   FROM titles
   WHERE type = 'business')
GO


下面是任一查询的结果集:

pub_name                                
----------------------------------------
Algodata Infosystems                    
New Moon Books                          

(2 row(s) affected)

C.比较使用 EXISTS 和 = ANY 的查询

本示例显示查找与出版商住在同一城市中的作者的两种查询方法:第一种方法使用 = ANY,第二种方法使用 EXISTS。注意这两种方法返回相同的信息。

 代码如下 复制代码

USE pubs
GO
SELECT au_lname, au_fname
FROM authors
WHERE exists
   (SELECT *
   FROM publishers
   WHERE authors.city = publishers.city)
GO

-- Or, using = ANY

USE pubs
GO
SELECT au_lname, au_fname
FROM authors
WHERE city = ANY
   (SELECT city
   FROM publishers)
GO


下面是任一查询的结果集:

au_lname                                 au_fname            
---------------------------------------- --------------------
Carson                                   Cheryl              
Bennet                                   Abraham             

(2 row(s) affected)

D.比较使用 EXISTS 和 IN 的查询

本示例所示查询查找由位于以字母 B 开头的城市中的任一出版商出版的书名:

 代码如下 复制代码

USE pubs
GO
SELECT title
FROM titles
WHERE EXISTS
   (SELECT *
   FROM publishers
   WHERE pub_id = titles.pub_id
   AND city LIKE 'B%')
GO

-- Or, using IN:

USE pubs
GO
SELECT title
FROM titles
WHERE pub_id IN
   (SELECT pub_id
   FROM publishers
   WHERE city LIKE 'B%')
GO


下面是任一查询的结果集:

title                                                                           
------------------------------------------------------------------------
The Busy Executive's Database Guide                                             
Cooking with Computers: Surreptitious Balance Sheets                            
You Can Combat Computer Stress!                                                 
Straight Talk About Computers                                                   
But Is It User Friendly?                                                        
Secrets of Silicon Valley                                                       
Net Etiquette                                                                   
Is Anger the Enemy?                                                             
Life Without Fear                                                               
Prolonged Data Deprivation: Four Case Studies                                   
Emotional Security: A New Algorithm                                             

(11 row(s) affected)

使用 NOT EXISTS
NOT EXISTS 的作用与 EXISTS 正相反。如果子查询没有返回行,则满足 NOT EXISTS 中的 WHERE 子句。本示例查找不出版商业书籍的出版商的名称:

 代码如下 复制代码

SELECT title
FROM titles
WHERE EXISTS
    (SELECT *
    FROM publishers
    WHERE pub_id = titles.pub_id
    AND city LIKE 'B%')


SELECT title
FROM titles
WHERE pub_id IN
    (SELECT pub_id
    FROM publishers
    WHERE city LIKE 'B%')

又比如以下 SQL 语句:

 代码如下 复制代码

select distinct 姓名 from xs
where not exists (
select * from kc
where not exists (
select * from xs_kc
where 学号=xs.学号 and 课程号=kc.课程号
)

把最外层的查询xs里的数据一行一行的做里层的子查询。

中间的 exists 语句只做出对上一层的返回 true 或 false,因为查询的条件都在 where 学号=xs.学号 and 课程号=kc.课程号这句话里。每一个 exists 都会有一行值。它只是告诉一层,最外层的查询条件在这里成立或都不成立,返回的时候值也一样回返回上去。直到最高层的时候如果是 true(真)就返回到结果集。为 false(假)丢弃。

 代码如下 复制代码

where not exists
select * from xs_kc
where 学号=xs.学号 and 课程号=kc.课程号

这个 exists 就是告诉上一层,这一行语句在我这里不成立。因为他不是最高层,所以还要继续向上返回。

select distinct 姓名 from xs where not exists (这里的 exists 语句收到上一个为 false 的值。他在判断一下,结果就是为 true(成立),由于是最高层所以就会把这行的结果(这里指的是查询条件)返回到结果集。

几个重要的点:

最里层要用到的醒询条件的表比如:xs.学号、kc.课程号等都要在前面的时候说明一下select * from kc,select distinct 姓名 from xs
不要在太注意中间的exists语句.
把exists和not exists嵌套时的返回值弄明白

相关文章

精彩推荐