關於exists 的使用

2021-08-30 17:15:20 字數 3771 閱讀 9287

--近來幹活時發現對同事寫的用exists的sql看不很懂,在網上蒐集了些資料學習學習。

--下面這些說法不見的都對,有不對的地方請高手指正。

1、exists 字面意思存在。

exists裡的子查詢結果集非空,exists()子句的值就是true。

exists裡的子查詢結果集為空,exists()子句的值就是false。

select * from scott.emp where exists(select sysdate from dual);

此句將查出scott.emp表所有內容.

select * from scott.emp where exists(select * from scott.salgrade where 1=2) ;

返回空結果集

帶有exists謂詞的子查詢不返回任何資料,只產生邏輯真值「true」或邏輯假值「false」。

使用存在量詞exists後,若內層查詢結果非空,則外層的where子句返回真值否則返回假值。

由exists引出的子查詢,其目標列表示式通常都用*,因為帶exists的子查詢只返回真值或假值,

給出列名無實際意義。

2、用exists的相關子查詢

子查詢的查詢條件依賴於外層父查詢的某個屬性值,稱這類查詢為相關子查詢。

求解相關子查詢不能像求解不相關子查詢那樣,一次將子查詢求解出來,然後求解父查詢。

內層查詢由於與外層查詢有關,因此必須反覆求值。

首先去外層查詢中表的第1個元組,根據它與內層查詢相關的屬性值處理內層查詢,

若where子句返回值為真,則取此元組放入結果表;然後再取表的下乙個元組;

重複這個過程直到外層表全部檢查完為止。

sql> select a.ename from scott.emp a

where exists(select * from scott.dept b where b.deptno=a.deptno);

ename

----------

smith

allen

ward

jones

martin

blake

clark

scott

king

turner

adams

james

ford

miller

查詢到14記錄.

相當於下sql:

select a.ename from scott.emp a

where a.deptno in (select b.deptno from scott.dept b );

exists子查詢實際是通過關聯別的表安某種條件縮小主查詢的範圍。

3、not exists 簡單的理解就是 not exists= not in

實際not exists 取得是不屬於exists限制條件的主表的資料集

sql> select a.ename from scott.emp a

where exists(select * from scott.dept b where b.deptno=a.deptno and b.deptno=10);

ename

----------

clark

king

miller

select a.ename from scott.emp a

where not exists(select * from scott.dept b where b.deptno=a.deptno and b.deptno=10)

ename

----------

smith

allen

ward

jones

martin

blake

scott

turner

adams

james

ford

查詢到11記錄.

4 、exists和in

in子句通常用在不相關子查詢中。通常先執行子查詢,將子查詢的結構用於父查詢。

子查詢的查詢條件不依賴於父查詢,這類子查詢稱為不相關子查詢。

關鍵字: 在oracle sql中取資料時in 和 exists 的區別?

在oracle sql中取資料時有時要用到in 和 exists 那麼他們有什麼區別呢?

1 效能上的比較

比如select * from t1 where x in ( select y from t2 )

執行的過程相當於:

select *

from t1, ( select distinct y from t2 ) t2

where t1.x = t2.y;

相對的

select * from t1 where exists ( select null from t2 where y = x )

執行的過程相當於:

for x in ( select * from t1 )

loop

if ( exists ( select null from t2 where y = x.x ) )

then

output the record

end if

end loop

表 t1 不可避免的要被完全掃瞄一遍

分別適用在什麼情況?

以子查詢 ( select y from t2 )為考慮方向,如果子查詢的結果集很大需要消耗很多時間,

但是t1比較小執行( select null from t2 where y = x.x )非常快,那麼exists就比較適合用在這裡。

相對應得子查詢的結果集比較小的時候就應該使用in.

5、問題: 我建立了乙個表來存放客戶資訊,我知道可以用 insert 語句插入資訊到表中,

但是怎麼樣才能保證不會插入重複的記錄呢?

答案: 可以通過使用 exists 條件句防止插入重覆記錄。

示例一:插入多條記錄

假設有乙個主鍵為 client_id 的 clients 表,可以使用下面的語句:

insert into clients

(client_id, client_name, client_type)

select supplier_id, supplier_name, 'advertising'

from suppliers

where not exists (select * from clients

where clients.client_id = suppliers.supplier_id);

個人批註:not exists不存在,也就是說後面的括號中只要返回了資料那麼這個條件就不存在了,

可以理解為括號前的notexists是乙個左表示式 ,括號後的查詢是乙個右表示式,

只有當右表示式返回的也是not exists(即後面的查詢出來的結果是非空的)時,等式才成立。

示例一:插入單條記錄

code:

insert into clients

(client_id, client_name, client_type)

select 10345, 'ibm', 'advertising'

from dual

where not exists (select * from clients

where clients.client_id = 10345);

使用 dual 做表名可以讓你在 select 語句後面直接跟上要插入欄位的值,即使這些值還不存在當前表中。

關於EXISTS的使用及效率

本文參考了不過的oracle部落格http www.cnblogs.com yf520gn archive 2009 01 12 1374359.html 後根據自己的理解來寫的。建立兩張表t1 t2,其中t1的locline列中的某些值存在於t2的location中 create table t1...

使用exists代替in

select from class a where id in select id from class b select from class a a where exists select from class b b where a.id b.id 分析 上述兩種方法查詢結果一樣,但exist...

SQL中EXISTS的使用

網上有一些關於exists 說明的例子,但都說的不是很詳細.比如對於著名的供貨商資料庫,查詢 找出 所有零件的 商的 商名,對於這個查詢,網上一些關於exists的說明文章都不能講清楚.我先解釋本文所用的資料庫例子,供貨商 資料庫,共3個表.供貨商表 s s sname 貨物表 p p pname ...