Exists 用法

一、用法

exists: ()內子查詢語句返回結果不為空,說明where條件成立就會執行主sql語句。如果為空就表示where條件不成立,sql語句就不會執行。not exists 和 exists相反,子查詢語句結果為空,則表示where條件成立,執行sql語句。否則不執行。

exists : 強調是否返回結果集,不要求知道返回什么,與in的區別就是,in只能返回一個字段值,exists允許返回多個字段。如:

select name from student where sex = 'm' and mark exists(select 1 from grade where ...) 

exists引導的子句有結果集返回,那么exists這個條件就算成立了,返回的字段始終為1,這個數字沒有意義。所以exists子句不在乎返回什么,而是在乎是不是有結果集返回。

  • exists (sql返回的結果為真)
  • not exists (sql不返回的結果為真)

exists 效率一般優于 in ,使用EXISTS,Oracle會首先檢查主查詢,然后運行子查詢知道它找到第一個匹配項,這就節省了時間。IN 子查詢時,首先執行子查詢,并將獲得的結果列表存放在一個加了索引的臨時表中。

exists 效率優于DISTINCT 當,提交一對多表信息的查詢時,避免在SELECT 子句中使用DISTINCT

exists適合外表的結果集小的情況
in適合內外表都很大的情況

二、實例

1.exists簡單用法

create table a(
  id int,
  name varchar(10)
);
insert into a values(1,'A1');
insert into a values(2,'A2');
insert into a values(3,'A3');
1.png
create table b(
  id int,
  aid int,
  name varchar(10)
);
insert into b values(1,1,'B1');
insert into b values(2,2,'B2');
insert into b values(3,2,'B3');
2.png

表A和表B示1對多的關系 A.ID => B.AID

SELECT ID,NAME FROM A WHERE 
EXISTS(SELECT * FROM B WHERE A.ID = B.AID)

執行結果:


3.png

分解

SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=1) 
--->SELECT * FROM B WHERE B.AID=1有值返回TRUE所以有數據 

SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=2) 
--->SELECT * FROM B WHERE B.AID=2有值返回TRUE所以有數據 

SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=3) 
--->SELECT * FROM B WHERE B.AID=3無值返回TRUE所以沒有數據 
  • NOT EXISTS 就是反過來

以上代碼等價于:

SELECT id, name from A WHERE id in (
select aid from B)

SQL中IN, NOT IN, EXISTS, NOT EXISTS 的用法和差別:

  • IN:確定給定的值是否與子查詢或列表中的值相匹配。IN關鍵字選擇與列表中的任意一個值匹配的行。IN 關鍵字之后的項目必須用逗號隔開,并且括在括號中。
  • NOT IN : 通過 NOT IN 關鍵字引入的子查詢也返回一列零值或更多值。
  • EXISTS 指定一個子查詢,檢測行的存在。相當于兩個集合的交集。EXISTS 后面可是整句的查詢語句,IN的后面只能是對單列。
  • NOT EXISTS 相當于兩個集合的差集。
  • EXISTS 和 NOT EXISTS 返回的結果類型是 Boolean,如果子查詢包含行,則返回TRUE/FALSE

二、EXISTS 替代DISTINCT

SELECT distinct dept_no, dept_name from dept D, EMP E 
WHERE D.dept_no = E.dept_no;
SELECT dept_no, dept_name from dept D 
WHERE EXISTS (
   SELECT 1 from emp E WHERE E.dept_no =D.dept_no
);

RDBMS 核心模塊將在子查詢的條件一旦滿足后,立即返回結果,所以自帶去重。

三、按A列去重,按B列取條件(如最大/小值等)

  1. 在下表中查詢出,同一ID內的B_DATE最近的記錄。


    4.png
SELECT * from t t1 
   WHERE NOT EXISTS(
      select * from t where id = t1.id and b_date>t1.b_date)

結果:


5.png

分析:
子查詢中,先看id = 1 的情形,只有當t1.b_date 取最大值時,沒有返回結果,因為是NOT EXISTS關鍵字,所以Where條件成立,返回符合條件的查詢結果。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容