連接查詢
若一個查詢同時涉及兩個或兩個以上的表,則稱之為連接查詢。連接查詢是數據庫中最最要的查詢,
包括:
1、等值連接查詢
2、自然連接查詢
3、非等值連接查詢
4、自身連接查詢
5、外連接查詢
6、復合條件查詢
等值與非等值連接查詢:
比較運算符主要有=、>、<、>=、<=、!=(或<>)等。
下面來看一個例子:
假設有一個學生數據庫,其中有三張表,即學生信息表(Student)、課程表(Course)、選課表(Study),三張表中的信息如下:



例1:要求查詢選修了課程的學生的信息
很顯然,需要用連接查詢,學生的情況存放在student表中,學生的選課情況存放在Study表中,所以查詢實際涉及Student和Study這兩個表。這兩個表之間的聯系是通過公共屬性Sno實現的。
考慮下列等值連接查詢語句
SELECT Student.*,Study.* FEOM Student,Study WHERE Student.Sno=Study.Sno /*將Student與Study中同一學生的元祖連接起來*/
得到的結果:
我們發現,上述查詢語句按照把兩個表中學號相等的元祖連接起來。
系統執行的連接過程:首先在表Student中找到一個元祖,然后從頭開始掃描Study表,逐一查找與Student第一個元祖的Sno相等的元祖,找到后就將Student表中的第一個元祖與該元祖拼接起來,形成結果表中的一個元祖,Stdudy表全部查找完后,再找Student中的第二個元祖,重復上述過程,直至Student表中的全部元祖處理完。
自然連接:在等值連接中把目標中重復的屬性列去掉的連接查詢
下面考慮用自然連接實現上述例子:
SELECT Student.Sno,SName,SSex,Sdept,Cno,Grade FROM Student,Study WHERE Student.Sno=Study.Sno
結果:
自身連接查詢:當查詢的結果涉及同一個表中兩個或以上的列時,考慮用自身連接查詢
例2:查詢每一門課的間接先行課(即先行課)
SELECT C1.Cpno FEOM Course AS C1,Course AS C2 <span style="white-space:pre;"> </span>--為Course表起兩個別名C1、C2 WHERE C1.Pcno=C2.Cno --兩個Course表的連接
結果:
外連接查詢:
分為左外連接,右外連接,
左外連接:根據左表的記錄,在被連接的右表中找出符合條件的記錄與之匹配,找不到匹配的,用null填充
右連接:根據右表的記錄,在被連接的左表中找出符合條件的記錄與之匹配,找不到匹配的,用null填充
例3:查詢缺少成績的的學生號和課程號:
SELECT Student.Sno,Cno FROM Student LEFT JOIN Study ON Student.Sno=Study.Sno WHERE Grade IS NULL
結果:
例4:查詢所有學生的學號姓名、成績
--左外連接
SELECT Student.Sno AS 學號,SName AS 姓名, Grade AS 成績 FROM Student LEFT JOIN Study<span style="white-space:pre;"> </span> ON Student.Sno=Study.Sno
相當於:
--右外連接
SELECT Student.Sno AS 學號,SName AS 姓名, Grade AS 成績 FROM Study RIGHT JOIN Student ON Study.Sno=Student.Sno
結果:
左外連接列出左邊關系,右外連接列出右外關系中所有的元祖
多表連接查詢:
--1、WHRER 語句
--2、INNER JOIN.. 語句
--1、WHRER 語句
--2、INNER JOIN.. 語句
例:查詢選修了C601號課程的學生姓名、分數、課程名
這個查詢三個涉及了表學生表、課程表和學習表’
SELECT Student.SName AS 學生姓名,Grade AS 成績,CName AS 課程名 FROM Student INNER JOIN Study ON Student.Sno=Study.Sno INNER JOIN Course ON Study.Cno=Course.Cno WHERE Course.Cno='C601'
相當於自然連接查詢:
SELECT Student.SName AS 學生姓名,Grade AS 成績,CName AS 課程名
FROM Student,Course,Study
WHERE Student=Study.Sno AND Study.cno=Course.Cno ADN Course.Cno=C601
嵌套查詢
嵌套查詢又稱子查詢,是指在父查詢的where條件語句中再插入一個子查詢語句,連接查詢都可以用子查詢完成,反之不然。
例1:找出至少一門課程的成績在90分以上的女學生的姓名
分析:已知的是分數大於90分這個條件,通過這個條件找出Study表中大於90分所對應的Sno,再通過連接查詢Study表中對應Sno的SName
SELECT SName FROM Student WHERE Sex='女' AND Sno NOT IN ( SELECT Sno FROM Stduy WHERE Grade<90 )
注意:這里子查詢返回的Sno可能有多個,所以要用到謂詞 IN,如果用 =,則報錯,因為 = 表示子查詢的返回值是唯一的。
子查詢的一個原則:根據已知得出未知
例2:查詢選修了課程名為 ‘’高等數學” 的學生學號和姓名
根據Course表中的高等數學得到課程號,再在Study表中找到選修了該課程號的學號,最后根據學號Sno在Student表中找出對應的學生的姓名。一層層嵌套,由已知得到未知。
SELECT Sno,SName FROM Student WHERE Sno IN ( SELECT Sno FROM Study WHERE Cno IN ( SELECT Cno FROM Course WHERE CName='高等數學' ) )
相當於連接查詢:
SELECT Student.Sno,SName FROM Student,Course,Study WHERE Student.Sno=Study.Sno AND Course.Cno=Study.Cno AND Course.CName='高等數學'
結果:
例3:找出至少學了C601和C602兩門課程的學生姓名。
這里涉及到兩門課程,都來自Course表,涉及到同一個表中兩個或以上的元祖,考慮子查詢用自身連,子查詢根據課程號返回學號,父查詢再根據學號查詢姓名。
SELECT SName FROM Student WHERE Sno IN ( SELECT Study1.Sno FROM Study AS Study1 JOIN Study AS Study2 ON Study1.Sno=Study2.Sno WHERE Study1.Cno='C601' AND Study2.Cno='C602' )
結果: