SQL 雙層 not exist 嵌套

來源:互聯網
上載者:User

很早的一個問題了,今天碰到又繞了一下。其實很簡單。

關係模式:
學生(學號,姓名,系別,年齡)
課程(課程號,課程名,學時)
選讀(學號,課程號,成績)
問題:檢索選讀全部課程的學生姓名
select 學生.姓名 from 學生
where not exists(
select * from 課程 where not exists(
select * from 選讀 where 學號=學生.學號 and 課程號=課程.課程號))

意思是
con1:這個學生不會con2。
con2:他有課沒選。

下面是網上關於這件事的討論,弄個合集防止腦子再發懵。。。
現在我們從後面的子查詢向前分解:

1.所有未選過的課程的資料集:
select * from 課程 where not exists(
select * from 選讀 where 課程號=課程.課程號)

2.所有沒被某位學號為 @學號 的學生選過的課程的記錄集(@學號學生的未選課程):
select * from 課程 where not exists(
select * from 選讀 where 學號=@學號 and 課程號=課程.課程號)
請注意,多出了學號的篩選即,學號=@學號。

3.遍曆每一個主查詢的學號,每一個學號都按第二篩選方法篩選出:沒有未選課程的學生的學號。(不包括在第查詢方法查詢出的“有未學課程的學號的記錄集”中的記錄。)
請注意:用主查詢中的 學生.學號 代替了@學號。
select 學生.姓名 from 學生
where not exists(
select * from 課程 where not exists(
select * from 選讀 where 學號=學生.學號 and 課程號=課程.課程號))

這已經是整個查詢語句,可以看出子查詢中用學生.學號替換了第2步中的 @學號,(沒忘了吧,第二步求的是沒有選修全部課程的某個學生)。

用上面的講解方法不知道是不是更好理解一點。

===============

針對您最後的補充:

為什麼不用
from 學生,課程,選讀?

答:因為from 學生,課程,選讀 也就是
SELECT * FROM 學生,課程,選讀 WHERE .....條件
這樣的型式只能組成內聯結,而內聯結我們只知道,只有三個表按聯結條件都符合才會被選中,而我們要的是有不符合後面兩表的的學生才符合條件,所以用內聯結是不可行的。

要不然where句怎麼可以調用三個關係的屬性呢?

答:在SQL SERVER中規定:所有子表都是可以通過表名調用其上面任意層次的表中的欄位的。所以,不是只有內聯結才可以調用多個表的屬性。




雙重否定
從最裡面開始執行

select * from 課程 where not exists(
select * from 選讀 where 學號=學生.學號 and 課程號=課程.課程號))
這段是返回某學生沒有選擇的課程,假設返回集a

前面套個not exists的後,
當a有值,即,某學生存在沒有選擇的課程時,整段sql文返回null,




在這裡http://www.blogjava.net/decode360/archive/2009/06/12/282804.html也有解釋。
當a無值,即,某學生不存在沒有選擇的課程時,就是說選擇了全部課程,整段sql文該學生返回姓名

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.