1. 程式人生 > >SQL之對EXISTS謂詞的理解

SQL之對EXISTS謂詞的理解

一、首先明確幾點:

  1. EXISTS相當於存在量詞彐
  2. EXISTS和NOT EXISTS不返回任何資料,只返回邏輯真或者假
  3. 由EXISTS引出的子查詢,其目標列表達式通常都用*,因為EXISTS的子查詢只返回真值或者假值,不返回選擇出來的結果,因此,你給什麼樣的列名最後返回的都是true或者false,所以給出實際列名無意義。
  • 例1:
SELECT sname
FROM student
WHERE exists
(
SELECT *
  FROM sc
  WHERE sc.sno=student.sno AND cno='1;
)

一、對上面的過程理解:

本查詢涉及表student和sc表。

在student表中從頭到尾每次取一個元組出來,用這個元組的sno與sc表所有的元組做比較,如果比較條件成立(sc表中存在sno值等於student.sno中值並且其cno='1’的元組),即exists語句中的SQL語句有返回值過來,則EXISTS返回給上一級元組一個true值-----表示允許現在student表中的這個元組可以放入結果表中。

二、注意:

1.首先子查詢中必須要有依賴父查詢的條件,即我們單獨把子查詢的select語句提出來不能正常執行。

2.每次查詢時父查詢表中的一個元組對子查詢所有的元組進行判定,如果為true則父查詢中的這個元組允許放入結果表,否則進行父查詢下一個元組的判定。

  • 例2

    查詢選修了所有課的學生姓名

    翻譯為:查詢這樣的學生姓名—不可能沒有選course裡面的課(因為是雙重否定,所以有兩個not exists)

    select sname
    from student
    where not exists/*查詢的學生不滿足這個條件(對sutdent限制)*/select *
        from course
        where not exists/*這個條件就是:沒有選Course裡面的課(對course限制)*/ 
            (select *
            from sc
            where sno =student.sno
            and
    cno=course.cno));
  • 例3

    查詢至少選修了學生201215122選修的全部課程的學生號碼

    翻譯:不存在這樣的課程y,學生201215122選修了y,而學生x沒有選

    SELECT DISTINCT Sno
    FROM SC SCX
    WHERE NOT EXISTS/*找的學生號碼不滿足以下條件*/
    		(SELECT * 
    		FROM SC SCY
    		WHERE SCY.Sno='201215122' AND/*201215122選了的課*/
    				NOT EXISTS(/*這門課在X中沒有被選擇(不存在)*/
    				SELECT * FROM SC SCZ
    				WHERE SCZ.Sno=SCX.Sno AND
    					  SCZ.Cno=SCY.Cno
    				));