oracle的exists用法總結


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 語句后面直接跟上要插入字段的值,即使這些值還不存在當前表中。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM