exists表示()內子查詢語句返回結果不為空說明where條件成立就會執行主sql語句,如果為空就表示where條件不成立,sql語句就 不會執行。not exists和exists相反,子查詢語句結果為空,則表示where條件成立,執行sql語句。負責不執行。
之前在學oracle數據庫的時候,接觸過exists,做過幾個簡單的例子,,如
1.如果部門名稱中含有字母A,則查詢所有員工信息(使用exists)
select * from emp where exists (select * from dept where dname like '%A%' and deptno = emp.deptno) temp and deptno=temp.deptno;
結果為:
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
7369 SMITH CLERK 7902 17-12月-80 800 20
7499 ALLEN SALESMAN 7698 20-2月 -81 1600 300 30
7521 WARD SALESMAN 7698 22-2月 -81 1250 500 30
7566 JONES MANAGER 7839 02-4月 -81 2975 20
7654 MARTIN SALESMAN 7698 28-9月 -81 1250 1400 30
7698 BLAKE MANAGER 7839 01-5月 -81 2850 30
7782 CLARK MANAGER 7839 09-6月 -81 2450 10
7788 SCOTT ANALYST 7566 19-4月 -87 3000 20
7839 KING PRESIDENT 17-11月-81 5000 10
7844 TURNER SALESMAN 7698 08-9月 -81 1500 0 30
7876 ADAMS CLERK 7788 23-5月 -87 1100 20
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
7900 JAMES CLERK 7698 03-12月-81 950 30
7902 FORD ANALYST 7566 03-12月-81 3000 20
7934 MILLER CLERK 7782 23-1月 -82 1300 10
已選擇14行。
2.如果有平均工資不小於1500的部門信息則查詢所有部門信息(使用not exists)
select * from dept where not exists (select deptno from emp where deptno = emp.deptno group by deptno having avg(sal) < 1500) and exists (select * from emp where emp.deptno = deptno);
--近來干活時發現對同事寫的用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 語句后面直接跟上要插入字段的值,即使這些值還不存在當前表中。