MySQL中的exist與not exists


准備數據

我們先介紹下使用的3個數據表:

student數據表:

course數據表:

sc數據表:

EXISTS

EXISTS代表存在量詞∃。帶有EXISTS謂詞的子查詢不返回任何數據,只產生邏輯真值“true”或者邏輯假值“false”。

一個例子1.1:

要求:查詢選修了課程”操作系統“的同學

SQL語句:

 

  1. SELECT Sname FROM student  
  2. WHERE EXISTS  
  3. (SELECT * FROM sc,course WHERE Sno=student.Sno AND sc.Cno=course.Cno AND course.Cname="操作系統")  
SELECT Sname FROM student
WHERE EXISTS
(SELECT * FROM sc,course WHERE Sno=student.Sno AND sc.Cno=course.Cno AND course.Cname="操作系統")

 

 

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

在本例中,首先分析最內層的語句:

 

  1. SELECT * FROM sc,course WHERE Sno=student.Sno AND sc.Cno=course.Cno AND course.Cname="操作系統"  
SELECT * FROM sc,course WHERE Sno=student.Sno AND sc.Cno=course.Cno AND course.Cname="操作系統"

本例中的子查詢的查詢條件依賴於外層父查詢的某個屬性值(本例中的是Student的Sno值),這個相關子查詢的處理過程是:

 

首先取外層查詢中(student)表的第一個元組,根據它與內層查詢相關的屬性值(Sno值)處理內層查詢,若外層的WHERE返回為真,則取外層查詢中該元組的Sname放入結果表;

然后再取(student)表的下一組,重復這一過程,直至外層(Student)表全部檢查完畢。

查詢結果表:

NOT EXISTS

與EXISTS謂詞相對的是NOT EXISTS謂詞。使用存在量詞NOT EXISTS后,若對應查詢結果為空,則外層的WHERE子語句返回值為真值,否則返回假值。

例子2.1:
要求:查詢沒有選修課程”操作系統“的同學

SQL語句:

 

  1. SELECT Sname FROM student  
  2. WHERE NOT EXISTS  
  3. (SELECT * FROM sc,course WHERE Sno=student.Sno AND sc.Cno=course.Cno AND course.Cname="操作系統")  
SELECT Sname FROM student
WHERE NOT EXISTS
(SELECT * FROM sc,course WHERE Sno=student.Sno AND sc.Cno=course.Cno AND course.Cname="操作系統")

 

 

使用NOT EXISTS之后,若內層查詢結果為非空,則對應的NOT EXISTS不成立,所以對應的WHERE語句也不成立。

在例子1.1中李勇同學對應的記錄符合內層的select語句的,所以返回該記錄數據,但是對應的NOT EXISTS不成立,WHERE語句也不成立,表示這不是我們要查詢的數據。

查詢結果表:

例子2.2(這是一個用NOT EXISTS表示全稱量詞的例子):

要求:查詢選修了全部課程的學生姓名。

SQL語句:

 

  1. SELECT Sname  
  2. FROM Student   
  3. WHERE NOT EXISTS  
  4. (SELECT * FROM Course WHERE NOT EXISTS  
  5.      (SELECT * FROM SC WHERE Sno=Student.Sno AND Cno=Course.Cno)  
  6. );  
SELECT Sname
FROM Student 
WHERE NOT EXISTS
(SELECT * FROM Course WHERE NOT EXISTS
     (SELECT * FROM SC WHERE Sno=Student.Sno AND Cno=Course.Cno)
);


這個算是一個比較復雜的sql語句了,兩個EXISTS和三個WHERE。

 

這個sql語句可以分為3層,最外層語句,最內層語句,中間層語句。

我們很關心最外層語句,因為結果表中的數據都是最外層的查詢的表中的數據,我們更關心最內層的數據,因為最內層的數據包含了全部的判斷語句,決定了student表中的那一條記錄是我們查詢的記錄。

我們由內而外進行分析:

最外層的student表中的第一條記錄是李勇同學對應的記錄,然后中間層的course表的第一條記錄是數據庫對應的記錄,然后對該數據進行判斷(最內層的WHERE語句),結果返回真,則內層的NOT EXISTS為假,

然后繼續對course表中的下一條記錄進行判斷,返現NOT EXISTS的值也為假,直到遍歷完course表中的所有的數據,內層的NOT EXISTS的值一直都是假,所以中間層的WHERE語句的值也一直都是假。

對應student的李勇記錄,course表中的所有的記錄對應的中間層的返回值為假,所以最外層的NOT EXISTS對應的值為真,最外層的WHERE的值也為真,則李勇對應的記錄符合查詢條件,裝入結果表中。

然后繼續對student表中的下一條記錄進行判斷,直達student表中的所有數據都遍歷完畢。

查詢結果表:

 


免責聲明!

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



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