基于 SQL 中的 EXISTS 运算符为我们提供了一种基于其他数据是否存在(或不存在)来检索数据的简便方法。更具体地说,它是一个逻辑运算符,用于评估子查询的结果,并返回一个布尔值,该值指示是否返回了行。尽管 IN 运算符可用于类似的目的,但需要注意它们之间的一些差异。今天的博客将介绍如何使用 EXISTS 运算符的几个示例,并提供一些指导,说明何时应使用 EXISTS 而不是 IN


EXISTS 在实践中的应用


尽管 EXISTS 运算符可以在 SELECTUPDATEINSERT DELETE 语句中使用,但为了保持简单,我们将重点介绍 SELECT 查询。因此,我们将使用的语法将非常类似于以下形式:


 


我们将在 PostgreSQL 的几个表上执行我们的查询——比如客户和账户表,这些表在银行数据库中很常见。下面是在 Navicat for PostgreSQL 网格视图中显示的这些表:



现在,我们可以使用以下查询来查看所有具有与其 customer_id 相关联的账户的客户:


 


以下是在 Navicat Premium 的查询编辑器中执行上述查询的结果:



使用 NOT EXISTS


相反地,在 EXISTS 运算符前加上 NOT 关键字会导致查询只选择子查询中没有匹配行的记录。我们可以使用 NOT EXISTS 来检索所有孤立的账户,即没有关联客户的账户:


 


由于客户表中没有该 ID 的客户,所以它返回了客户 #4 的账户。



Joins 替换 EXISTS


使用 EXISTS 运算符的查询可能执行起来有点慢,因为子查询需要对外层查询的每一行都执行一次。因此,你应该尽可能考虑使用连接。事实上,我们可以使用 LEFT JOIN 来重写上面的EXISTS 查询:


 

 


IN vs EXISTS 运算符


尽管 IN 运算符通常用于为列的某个值列表设置过滤器,但它也可以应用于子查询的结果。以下是我们第一个查询的等效查询,但这次使用的是 IN 而不是 EXISTS


 


请注意,我们只能选择想要进行比较的列,而不能选择 SELECT *。不过,IN 查询会产生相同的结果:



由于这两个操作符非常相似,数据库开发人员往往不确定应该使用哪一个。一般来说, 当你想根据特定值列表筛选行时,应该使用 IN 操作符。当你想检查子查询中是否存在满足某些条件的行时,应该使用 EXISTS