SQL全稱量詞

在王珊、薩師煊的《數據庫系統概論》第五版書中的P108例子比較難理解。

存在量詞

EXISTS謂詞:
帶有EXISTS謂詞的子查詢不返回任何數據,只產生邏輯真值“true”或邏輯假值“false”。
若內層查詢結果非空,則外層的WHERE子句返回真值;
若內層查詢結果爲空,則外層的WHERE子句返回假值。
由EXISTS引出的子查詢,其目標列表達式通常都用* ,因爲帶EXISTS的子查詢只返回真值或假值,給出列名無實際意義。
NOT EXISTS謂詞
若內層查詢結果非空,則外層的WHERE子句返回假值;
若內層查詢結果爲空,則外層的WHERE子句返回真值。

SQL中沒有全稱量詞,可以把帶有全稱量詞的謂詞轉換爲等價的帶有存在量詞的謂詞。

【例3.62】查詢選修了全部課程的學生姓名

SELECT Sname
FROM Student
WHERE NOT EXISTS
  ( SELECT *
    FROM Course
    WHERE NOT EXISTS
      ( SELECT *
        FROM SC
        WHERE Sno = Student.Sno AND Cno = Course.Cno
      )
  );
    

理解這個代碼,可以舉反例。

對於一個學生,如果他有一門課程沒有選,那麼這個學生就不屬於選修了全部課程的學生。

所以要找的學生是這樣一些學生。

課表上的每一門課,如果有課程沒有選,就把他歸類到有課程沒選的學生羣體裏。

而所要找的學生就是不在上面這個羣體裏的學生。

代碼遍歷學生表,對於每一個學生,在課程表中找,當該學生有課程沒選時,內層NOT EXISTS爲true,此時外層NOT EXISTS爲false。只有所有課程都選了,內層才爲false,此時外層就爲true了,表明該學生所有的課都選了。

【例3.63】查詢至少選修了學生201215122選修的全部課程的學生學號。

SELECT DISTINCT Sno
FROM SC SCX
WHERE NOT EXISTS
  ( SELECT *
    FROM SC SCY
    WHERE SCY.Sno = '20121522' AND NOT EXISTS
      ( SELECT *
        FROM SC SCZ
        WHERE SCZ.Sno = SCX.Sno AND SCZ.Cno = SCY.Cno
      )
  );
    

對於每個學生,不在這樣的學生羣體中。

該羣體爲對於學號爲20121522的學生所修的每一門課程,只要有一門課,有個學生沒有選,那麼這個學生就被加到這個羣體裏,意味着第二個NOT EXISTS爲true,此時第一個NOT EXISTS爲false。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章