首先頭腦中有三點概念:php
1 。 EXISTS子查詢找到的提交html
NOT EXISTS 子查詢中 找不到的提交算法
說明:不要去翻譯爲存在和不存在,把腦殼搞暈。數據庫
2 。 創建程序循環的概念,這是一個動態的查詢過程。如 FOR循環 。編程
3 。 Exists執行的流程Exists首先執行外層查詢,再執行內存查詢,與IN相反。 流程爲首先取出外測試
層中的第 一 元組, 再執行內層查詢,將外層表的第一元組代入,若內層查詢爲真,即有結果url
時。返回外層表中的第一元組,接着取出第二元組,執行相同的算法。一直到掃描完外層整表 。翻譯
for(int i =0; i<>EOFout;i++)htm
{內存
for (int j = 0 ; j<EOFint,j++)
}
而後再來看一個例子:三張表 學生表student (Sno,Sname), 課程表course (Cno,Cname)選課表SC
(Sno,Cno)
要求查詢出 :選修了所有課程的學生姓名
個人思路:
首先學生的選課信息存在於SC表中, 要想知道某個學生是否選修了所有課程,至少咱們須要知道一共有
幾門課程,這是首要的條件。其次,學生選修了與否,咱們又要掃描SC全表,統計出選修了全部課程的
學生號,最後在STUDENT表中根據學生號打出姓名 。
語句以下: (已測試)
select Sname from student
where Sno IN
(select Sno from SC
group by Sno //根據Sno分組,統計每一個學生選修了幾門課程。若是等於course的總數,就是咱們要找的Sno
having count(*) = (select count(*) from course )) //統計course中共有幾門課程
另外一種思路:
引入:將題目換爲查找學號爲 00003 沒有選修的科目
思路:咱們能夠將已知學號代入,把每個科目代入(循環),這將造成1*count(*)種組合。
將這組成做爲條件,一一與SC表種進行比對,找不到匹配的咱們提交 。
select Cname from course where
not exists //找不到的組合,提交course
(select * from SC where course.cno = cno and sno = ''00002'')
//在SC中匹配
換個題目: 查找沒有 沒有選修科目的學生姓名
思路:學號未知 , 科目未知,說明有兩個未知變量。應該有兩個EXISTS。咱們能夠掃描
student 和 course共有 s * c 中組合,將這些組合與SC的每一項進行匹配,注意s*c組合已經包含所
有可能。若是所有找到,就說明已經選修了所有課程。找不到就說明有課程沒選修 。再將沒選修的的
提交給上一exists循環 。若上一exists不存在的再提交給外循環。
select Sname from student
where NOT exists //
(select * from course
where NOT exists //不存在的提交給course
(select * from SC where
Sno = student.sno and cno = Course.Cno)) //代入兩個未知變量
回頭看,就是咱們第一個引出的題目:
選修了所有課程的學生姓名
首先頭腦中有三點概念:
1 。 EXISTS 子查詢找到的提交
NOT EXISTS 子查詢中 找不到的提交
說明:不要去翻譯爲存在和不存在,把腦殼搞暈。
2 。 創建程序循環的概念,這是一個動態的查詢過程。如FOR循環 。
3 。 Exists執行的流程Exists首先執行外層查詢,再執行內存查詢,與IN相反。 流程爲首先取出外
層中的第一元組,再執行內層查詢,將外層表的第一元組代入,若內層查詢爲真,即有結果
時。返回外層表中的第一元組,接着取出第二元組,執行相同的算法。一直到掃描完外層整表 。
for(int i =0; i<>EOFout;i++)
{
for (int j = 0 ; j<EOFin,j++)
}
而後再來看一個例子:三張表 學生表student (Sno,Sname),課程表course (Cno,Cname)選課表SC
(Sno,Cno)
要求查詢出:選修了所有課程的學生姓名
個人思路:
首先學生的選課信息存在於SC表中, 要想知道某個學生是否選修了所有課程,至少咱們須要知道一共有
幾門課程,這是首要的條件。其次,學生選修了與否,咱們又要掃描SC全表,統計出選修了全部課程的
學生號,最後在STUDENT表中根據學生號打出姓名 。
語句以下: (已測試)
select Sname from student
where Sno IN
(select Sno from SC
group by Sno //根據Sno分組,統計每一個學生選修了幾門課程。若是等於course的總數,就是咱們要找的Sno
having count(*) = (select count(*) from course )) //統計course中共有幾門課程
另外一種思路:
引入:將題目換爲查找學號爲 00003 沒有選修的科目
思路:咱們能夠將已知學號代入,把每個科目代入(循環),這將造成1*count(*)種組合。
將這組成做爲條件,一一與SC表種進行比對,找不到匹配的咱們提交 。
select Cname from course where
not exists //找不到的組合,提交course
(select * from SC where course.cno = cno and sno = ''00003'')
//在SC中匹配
換個題目:查找沒有 沒有選修科目的學生姓名
思路:學號未知 , 科目未知,說明有兩個未知變量。應該有兩個EXISTS。咱們能夠掃描
student 和 course共有 s * c 中組合,將這些組合與SC的每一項進行匹配,注意s*c組合已經包含所
有可能。若是所有找到,就說明已經選修了所有課程。找不到就說明有課程沒選修 。再將沒選修的的
提交給上一exists循環 。若上一exists不存在的再提交給外循環。
最後詳細回答你的問題:數據庫SQL語句中 查詢選修了所有課程的學生的學號和姓名
查詢選修了所有課程的學生姓名。
SELECT Sname
FROM Student
WHERE NOT EXISTS
(SELECT *
FROM Course
WHERE NOT EXISTS
(SELECT *
FROM SC
WHERE Sno= Student.Sno
AND Cno= Course.Cno);
理解以下: 查詢選修了所有課程的學生姓名。
不用管怎麼樣,第一個select一定是在 student表裏選 sname既:
SELECT Sname
FROM Student
加上條件即: where
條件是什麼呢?條件就是---------------------》 查詢選修了所有課程的
由於沒有 (任意一個)謂詞, 只能用 EXISTS 或者 NOT EXISTS來表示。 這點理解吧?
因此要把條件翻譯成 -----------------------》 不存在一門課程這個學生沒有選修
where後面就是 不存在(NOT EXISTS) (
一門課程這個學生沒有選修
)
接下來就是把Course表中的課程依次拿出來找出 沒有選修的
怎麼找呢? 由於 NOT EXISTS子查詢中 找不到的提交
另外你要明白 ----------------------------NOT EXISTS查詢 都是相關查詢----------
因此只要把在最後一個select 中
WHERE Sno= Student.Sno
AND Cno= Course.Cno);
就是將這個同窗經過 SC表 和 Crouse的 課程鏈接一遍,找到鏈接不上的,即: 沒有選修的, 這樣就找到了一門課這個學生沒有選修, 存在沒有選修的課,那麼該學生被pass掉了,
一次進行一個同窗的判斷 。
若你學過程序編程,能夠看下面的內容, 若沒有則可忽略、。----------
上述是理解是數據庫系統內部的實現,能夠用for循環表示
for(i=1; i<student.length( 學生的總人數); i++){
for(i=j;j<Crouse.length(總的課門數); j++){
條件就是:
沒有一門課沒有選修
}
}
最後你找記住
1. 第一個select就是 你要選的就是 學生
SELECT Sname
FROM Student
2. 第二個 select 就是 課程
3. 第三個select就是 學生和課程發生關係的表 ------------SC選修表
讓他們鏈接起來
固定的模式 1你要的結果的表 學生
2 知足條件的表 課程表
3 產生關係的表 選修表
where 經過選修表把他們鏈接起來
============================
查詢select----存在量詞查詢
exists表明存在量詞ョ,該查詢結果沒有值,只有邏輯值真true和邏輯假false兩個值。
ex41:查詢全部選修了001課程的學生名單
select sname
from student a
where exists (
select *
from sc b
where a.sno=b.sno and cno='001')
ex42:查詢沒有選修了001課程的學生名單
select sname
from student a
where not exists (
select *
from sc b
where a.sno=b.sno and cno='001')
ex43:查詢選修了全部課程的學生名單。
因爲SQL中沒有全稱量詞,能夠這樣理解:查詢這樣的學生,沒有一門課程他沒有選
select sname
from student a
where not exists (
select *
from course b
where not exists (
select *
from sc c
where a.sno=c.sno and c.cno=b.cno))
注意:SQL沒有蘊涵謂詞,可使用等價變換進行轉換
p→q ≡ ┑p∨q
ex43:查詢至少選修了學生95002選修的所有課程的學生名單。
將查詢進行變換:
p表示的謂詞:95002選修了課程y
q表示的謂詞:學生x選修了課程y
該查詢轉換爲:( y)p→q
進一步轉換:( y)p→q ≡
┑(ョy( ┑(p→q))) ≡ ┑(ョy( ┑(┑p∨q)))
≡ ┑ョy(p∧q)德模根定律
它所表達的含義爲:不存在這樣的課程y,95002選修了y而x沒有選,SQL語句以下:
select sname,snofrom student awhere sno <> '95002' and not exists ( select *from sc bwhere sno='95002' and not exists (select *from sc cwhere a.sno=c.sno and c.cno=b.cno))