在本教程中,您将学习如何使用oracle exists运算符来测试行的存在。
oracle exists运算符
oracle exists运算符是返回true或false的布尔运算符。exists运算符通常与子查询一起使用来测试行的存在:
select
*
from
table_name
where
exists(subquery);
如果子查询返回任何行,则exists运算符返回true,否则返回false。 另外,当子查询返回第一行,exists操作符终止子查询的处理。
oracle exists示例
下面来看看一些使用exists运算符的例子,来理解它是如何工作的。
1. oracle exists带有select语句的示例
请参阅示例数据库中的以下customers和orders表,它们的er图所下所示:
以下示例使用exists运算符来查找所有有订单的客户。
select
name
from
customers c
where
exists (
select
1
from
orders
where
customer_id = c.customer_id
)
order by
name;
执行上面查询语句,得到以下结果 -
对于customers表中的每个客户,子查询检查客户是否出现在orders表上。如果是,则exists操作符返回true并停止扫描orders表。 否则,如果子查询在orders表中找不到客户信息,则exists操作符返回false。
如果where子句使用exists运算符来检索使子查询的客户,则返回相关的行。
请注意,oracle会忽略子查询中的选择列表,因此您可以使用任何列,字面值,表达式等。在上面的查询中是使用了文字数字值: 1。
2. oracle exists带有update语句示例
请参阅以下仓库(warehouses)和位置(locations)表,它们之间的er图如下:
以下语句将更新位于美国的仓库的名称:
update
warehouses w
set
warehouse_name = warehouse_name || ', usa'
where
exists (
select
1
from
locations
where
country_id = 'us'
and location_id = w.location_id
);
对于每个仓库,子查询检查其位置是否在美国(us)。如果是,则where子句中的exists运算符返回true,使外部查询将字符串",usa"附加到仓库名称。否则,由于条件是where子句为false,update语句将什么都不做。
以下查询语句查询仓库名称以验证更新:
select
warehouse_name
from
warehouses
inner join locations
using(location_id)
where
country_id = 'us';
执行上面查询语句,得到以下结果 -
3. oracle exists与insert语句的例子
假设,我们需要向所有2016年订单的客户发送特殊的赞赏邮件。为此,首先创建一个新表来存储客户的数据:
drop table customers_2016;
create table customers_2016(
company varchar2(255) not null,
first_name varchar2(255) default null,
last_name varchar2(255) default null,
email varchar2(255) default null,
sent_email char(1) default 'n'
);
然后,将2016年有订单的客户信息插入到customers_2016表中,参考以下查询语句:
insert
into
customers_2016(
company,
first_name,
last_name,
)select
name company,
first_name,
last_name,
from
customers c
inner join contacts on
contacts.customer_id = c.customer_id
where
exists(
select * from orders
where customer_id = c.customer_id and extract(year from order_date)='2016'
)
order by
company;
执行上面查询语句,然后查询select * from customers_2016;得到以下结果 -
4. oracle exists与in
exists操作符在子查询返回第一行时停止扫描行,因为它可以确定结果,而in操作符必须扫描子查询返回的所有行以结束结果。
另外,in子句不能与null值进行任何比较,但exists子句可以将所有值与null值进行比较。例如,第一个语句不返回行记录,而第二个语句返回customers表中的所有行:
-- 第一个语句
select
*
from
customers
where
customer_id in(null);
-- 第二个语句
select
*
from
customers
where
exists (
select
null
from
dual
);
通常,当子查询的结果集较大时,exists运算符比in运算符更快。相比之下,当子查询的结果集很小时,in运算符比exists运算符更快。
在本教程中,您已学习如何使用oracle exists运算符来测试查询中是否存在行。