SQL連接查詢和嵌套查詢詳解


 連接查詢

若一個查詢同時涉及兩個或兩個以上的表,則稱之為連接查詢。連接查詢是數據庫中最最要的查詢,
包括:
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.. 語句
 
例:查詢選修了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'
)

  結果:

 

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM