實驗五 連接、嵌套和集合查詢

實驗五 連接、嵌套和集合查詢

課時分配:4課時

實驗性質:綜合

實驗主要內容及方法:各種連接、嵌套和集合查詢方法

實驗要求:

(1) 掌握連接、嵌套和集合查詢語句的一般格式。;

(2) 掌握連接、嵌套和集合查詢的各種使用方法。

實驗目的:熟練掌握連接、嵌套和集合查詢的使用。

實驗設備:裝有SQL SERVER 2005的電腦

實驗步驟:

(1) 啓動2005 SQL Server Management studio;

(2) 啓動數據庫引擎查詢;

(3) 在實驗四數據庫的基礎上,綜合練習如下例題:

一、連接查詢

1 不同表之間的連接查詢

例3.37  查詢每個學生及其選修課程的情況。

本查詢實際上是涉及Students與Reports兩個表的連接操作。這兩個表之間的聯繫是通過公共屬性Sno實現的,因此,其操作命令爲:

SELECT Students.*, Reports.*
FROM Students, Reports
WHERE Students.Sno = Reports.Sno

說明:若在以上等值連接中把目標列中重複的屬性列去掉則爲自然連接其命令爲
去除重複的sno

SELECT Students.Sno, Sname, Ssex, Sage, Sdept, Cno, Grade
FROM Students, Reports
WHERE Students.Sno= Reports.Sno;

例3.38 查詢每個學生的學號(Sno)、姓名(Sname)、選修的課程名(Cname)及成績(Grade)。

本查詢涉及到三個表的連接操作,完成該查詢的SQL語句如下:

SELECT Students.Sno, Sname, Cname, Grade
FROM Students, Reports, Courses
WHERE Students.Sno=Reports.Sno  AND
Reports.Cno=Courses.Cno;

 

2 自身連接

例3.39 查`詢每一門課的間接先修課(即先修課的先修課)。

在Courses表關係中,只有每門課的直接先修課信息,而沒有先修課的先修課。要得到這個信息,必須先對一門課找到其先修課,再按此先修課的課程號,查找它的先修課程。這就需要要將Courses表與其自身連接。爲方便連接運算,這裏爲Courses表取兩個別名分別爲A,B。則完成該查詢的SQL語句爲:

SELECT A.Cno, A.Cname, B.Pre_Cno
FROM Courses A, Courses B
WHERE A.Pre_Cno =B.Cno;

3 外連接

例3.40把例3.37中的等值連接改爲左連接。該左連接操作在SQL Server 2005中的命令格式爲:

SELECT Students.Sno, Sname, Ssex, Sdept, Cno, Grade
FROM Students
LEFT JOIN Reports ON
Students.Sno= Reports.Sno;

說明:以上左連接操作也可以用如下的右連接操作代替,其結果完全一樣。

SELECT Students.Sno, Sname, Ssex, Sdept, Cno, Grade
FROM Reports
RIGHT JOIN Students ON
Reports.Sno=Students.Sno;

二、嵌套查詢

1 帶謂詞IN的嵌套查詢

例3.41 查詢選修了編號爲“C02”的課程的學生姓名(Sname)和所在系(Sdept)。

SELECT Sname, Sdept
FROM Students
WHERE Sno IN
(SELECT Sno
FROM Reports
WHERE Cno='C02');

例3.42 查詢與“李偉”在同一個系學習的學生學號(Sno)、姓名(Sname)和系名(Sdept)。

該查詢可構造嵌套查詢實現,其SQL語句如下:

SELECT Sno, Sname, Sdept
FROM Students
WHERE Sdept IN
(SELECT Sdept
FROM Students
WHERE Sname='李偉');

說明:本例中的查詢也可以用自身連接來完成,其SQL語句如下:

SELECT A.Sno , A.Sname , A.Sdept
FROM Students A , Students B
WHERE A.Sdept=B.Sdept AND B.Sname='李偉';

例3.43  查詢選修了課程名爲“數據結構”的學生學號(Sno)和姓名(Sname)。

本查詢涉及學號、姓名和課程名(Cname)三個屬性。學號和姓名存放在Students表中,課程名的存放在Courses表中,但Students與Courses兩個表之間沒有公共屬性,必須通過Reports表建立它們之間的聯繫。所以本查詢實際上涉及三個關係的連接操作。

SELECT Sno, Sname /* ③最後在Studenst關係中 */
FROM Students /* 取出Sno和Sname */
WHERE Sno IN
(SELECT Sno /*② 然後在SC關係中找出 */
FROM Reports /*選修了3號課程的學生學號*/
WHERE Cno IN
(SELECT Cno /*① 首先在Courses關係中 */
FROM Courses /*找出“數據結構”的課程號,*/
WHERE Cname = '數據結構')); /*結果爲C02號 */

說明:本查詢同樣可以用連接查詢實現:

SELECT S.Sno, Sname
FROM Students S, Reports R, Courses C
WHERE S.Sno=R.Sno AND R.Cno=C.Cno AND C.Cname='數據結構';

2 帶有比較運算符的嵌套查詢

例3.44 將例3.42改爲帶有比較運算符的嵌套查詢。由於一個學生只可能在一個系學習,因此子查詢的結果是一個值,因此可以用=代替IN,其SQL語句如下:

SELECT Sno , Sname, Sdept
FROM Students
WHERE Sdept =
(SELECT Sdept
FROM Students
WHERE Sname='李偉');

3 帶謂詞ANY或ALL的嵌套查詢

例3.45  查詢非自動化系的不超過自動化系所有學生的年齡的學生姓名(Sname)和年齡(Sage)。其查詢命令爲

 

SELECT Sname, Sage
FROM Students
WHERE Sdept<>'自動化'
AND Sage<=ALL (SELECT Sage
FROM Students
WHERE Sdept= '自動化');

 

說明:本查詢也可以用集函數來實現。其SQL語句如下:

SELECT Sname, Sage
FROM Students
WHERE Sdept<>'自動化'
AND Sage<= (SELECT MIN(Sage)
FROM Students
WHERE Sdept='自動化');

4 帶謂詞EXISTS的嵌套查詢

例3.46  查詢所有選修了編號爲“C01”課程的學生姓名(Sname)和所在系(Sdept)。

本查詢的SQL語句是:

SELECT Sname, Sdept
FROM Students
WHERE EXISTS
(SELECT *
FROM Reports
WHERE Sno=Students.Sno AND Cno='C01');

 

例3.47 將例3.42改爲帶謂詞EXISTS的查詢,其SQL語句如下

 

SELECT Sno, Sname, Sdept
FROM Students A
WHERE EXISTS
(SELECT *
FROM Students B
WHERE B.Sdept=A.Sdept AND B.Sname='李偉');

 

例3.48  查詢選修了所有課程的學生姓名(Sname)和所在系。

由於沒有全稱量詞,可將題目的意思轉換成等價的用存在量詞的形式:查詢這樣的學生,沒有一門課程是他不選修的。其SQL語句爲:

SELECT Sname, Sdept
FROM Students
WHERE NOT EXISTS
(SELECT *
FROM Courses
WHERE NOT EXISTS
(SELECT * FROM Reports WHERE Sno=Students.Sno
AND Cno=Courses.Cno));

 

三、集合查詢

例3.49 查詢計算機科學系的學生或年齡不大於20歲的學生信息。

 

SELECT *
FROM Students
WHERE Sdept='計算機'
UNION
SELECT *
FROM Students
WHERE Sage<=20;

 

例3.50  查詢數學系的學生且年齡不大於20歲的學生的交集,這實際上就是查詢數學系中年齡不大於20歲的學生。

 

SELECT *
FROM Students
WHERE Sdept='數學' AND Sage<=20;

例3.51  查詢數學系的學生與年齡不大於20歲的學生的差集。

本查詢的等價說法是,查詢數學系中年齡大於20歲的學生。

 

SELECT *
FROM Students
WHERE Sdept='數學' AND Sage>20;

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