我想網(wǎng)關(guān)鍵詞優(yōu)化舉例
目錄
- 實驗?zāi)康?/li>
- 實驗內(nèi)容
- 實驗要求
- 實驗過程
- 實驗代碼
- 結(jié)果示意
書接上文,但是感覺之前的形式不太好用,至少不是很方便觀看,所以這篇嘗試改變一下寫法,希望可以提升一些觀感
實驗?zāi)康?/h2>
(1) 掌握RDBMS的數(shù)據(jù)多表查詢功能
(2) 掌握SQL語言的數(shù)據(jù)多表查詢語句
實驗內(nèi)容
(1) 等值連接查詢(含自然連接查詢)與非等值連接查詢
(2) 自身連接查詢
(3) 外連接查詢
(4) 復(fù)合條件連接查詢
(5) 嵌套查詢(帶有IN謂詞的子查詢)
(6) 嵌套查詢(帶有比較運算符的子查詢)
(7) 嵌套查詢(帶有ANY或ALL謂詞的子查詢)
(8) 嵌套查詢(帶有EXISTS謂詞的子查詢)
(9) 集合查詢
實驗要求
(1) 熟練掌握SQL的連接查詢語句
(2) 熟練掌握SQL的嵌套查詢語句
(3) 掌握表名前綴、別名前綴的用法
(4) 掌握不相關(guān)子查詢和相關(guān)子查詢的區(qū)別和用法
(5) 掌握不同查詢之間的等價替換方法(一題多解)及限制記錄實驗結(jié)果,認真完成實驗報告
實驗過程
建立示例數(shù)據(jù)庫S_T(復(fù)習(xí))
表Student
學(xué)號
Sno 姓名
Sname 性別
Ssex 年齡
Sage 所在系
Sdept
200215121 李勇 男 20 CS
200215122 劉晨 女 19 CS
200215123 王敏 女 18 MA
200215125 張立 男 19 IS
表Course
課程號
Cno 課程名
Cname 現(xiàn)行課
Cpno 學(xué)分
Ccredit
1 數(shù)據(jù)庫 5 4
2 數(shù)學(xué) 2
3 信息系統(tǒng) 5 4
4 操作系統(tǒng) 6 3
5 數(shù)據(jù)結(jié)構(gòu) 7 4
6 數(shù)據(jù)處理 2
7 PASCAL語言 6 4
表SC
學(xué)號
Sno 課程號
Cno 成績
Grade
200215121 1 92
200215121 2 85
200215121 3 88
200215122 2 90
200215122 3 80
實驗代碼
在SQL Server集成管理器的查詢窗口中輸入如下SQL語句序列來創(chuàng)建示例數(shù)據(jù)庫。
/* 創(chuàng)建示例數(shù)據(jù)庫S_T,包括3個表,即學(xué)生表Student、課程表Course和選課表SC*/
create database S_T;
go
use S_T; /*將S_T設(shè)為當(dāng)前數(shù)據(jù)庫*/
create table Student(Sno CHAR(9) PRIMARY KEY,Sname CHAR(20) UNIQUE,Ssex CHAR(2),Sage SMALLINT,Sdept CHAR(20));
go
/表Student的主碼為Sno,屬性列Sname取唯一值/
create table Course(Cno CHAR(4) PRIMARY KEY,Cname CHAR(40),Cpno CHAR(4),Ccredit SMALLINT,FOREIGN KEY (Cpno) REFERENCES Course(Cno));
go
/表Course的主碼為Cno,屬性列Cpno(先修課)為外碼,被參照表為Course,被參照列是Cno/
create table SC(Sno CHAR(9),Cno CHAR(4),Grade SMALLINT,primary key (Sno, Cno),FOREIGN KEY (Sno) REFERENCES Student(Sno),FOREIGN KEY (Cno) REFERENCES Course(Cno));
go
/表SC的主碼為(Sno, Cno), Sno和Cno均為外碼,被參照表分別為Student和Course,被參照列分別為Student.Sno和Course.Cno/
insert into student values('200215121','李勇','男',20,'CS');
insert into student values('200215122','劉晨','女',19,'CS');
insert into student values('200215123','王敏','女',18,'MA');
insert into student values('200215125','張立','男',19,'IS');
go
/為表Student添加數(shù)據(jù)/
insert into course values('1', '數(shù)據(jù)庫', NULL,4);
insert into course values('2', '數(shù)學(xué)', NULL,2);
insert into course values('3', '信息系統(tǒng)', NULL,4);
insert into course values('4', '操作系統(tǒng)', NULL,3);
insert into course values('5', '數(shù)據(jù)結(jié)構(gòu)', NULL,4);
insert into course values('6', '數(shù)據(jù)處理', NULL, 2);
insert into course values('7', 'PASCAL語言', NULL,4);
go
update Course set Cpno = '5' where Cno = '1';
update Course set Cpno = '1' where Cno = '3';
update Course set Cpno = '6' where Cno = '4';
update Course set Cpno = '7' where Cno = '5';
update Course set Cpno = '6' where Cno = '7';
go
/為表Course添加數(shù)據(jù)/
insert into SC values('200215121', '1',92);
insert into SC values('200215121', '2',85);
insert into SC values('200215121', '3',88);
insert into SC values('200215122', '2',90);
insert into SC values('200215122', '3',80);
go
也可以將上述SQL語句序列預(yù)先保存在S_T.sql文件中,在SSMS中打開并執(zhí)行該文件中的sql語句序列
對學(xué)生關(guān)系Student、課程關(guān)系Course和選修關(guān)系SC進行多表查詢
基本練習(xí)
(1)等值連接查詢與自然連接查詢
例如:查詢每個學(xué)生及其選修課的情況。
SELECT Student.*, SC.*
FROM Student, SC
WHERE Student.Sno = SC.Sno; /* 一般等值連接 */
又如:查詢每個學(xué)生及其選修課的情況(去掉重復(fù)列)
SELECT Student.Sno, Sname, Ssex, Sage, Cno, Grade
FROM Student, SC
WHERE Student.Sno = SC.Sno; /* 自然連接--特殊的等值連接 */
(2)自身連接查詢
例如:查詢每一門課的間接先修課。
SELECT FIRST.Cno, SECOND.Cpno
FROM Course FIRST, Course SECOND
WHERE FIRST.Cpno = SECOND.Cno;
(3)外連接查詢
例如:查詢每個學(xué)生及其選修課的情況(要求輸出所有學(xué)生–含未選修課程的學(xué)生的情況)
SELECT Student.Sno, Sname, Ssex, Sage, Sdept, Cno, Grade
FROM Student LEFT OUTER JOIN SC ON(Student.Sno = SC.Sno);
(4)復(fù)合條件連接查詢
例如:查詢選修了2號課程而且成績在90以上的所有學(xué)生的學(xué)號和姓名。
SELECT Student.Sno,Sname
FROM Student,SC
WHERE Student.Sno = SC.Sno ANDSC.Cno = '2' AND SC.Grade >= 90;
又如:查詢每個學(xué)生的學(xué)號、姓名、選修的課程名及成績。
SELECT Student.Sno, Sname, Cname, Grade
FROM Student, SC, Course
WHERE Student.Sno = SC.Sno ANDSC.Cno = Course.Cno;
(5)嵌套查詢(帶有IN謂詞的子查詢)
例如:查詢與“劉晨”在同一個系學(xué)習(xí)的學(xué)生的學(xué)號、姓名和所在系。
SELECT Sno, Sname, Sdept
FROM Student
WHERE Sdept IN (SELECT SdeptFROM StudentWHERE Sname = '劉晨'); /* 解法一*/
可以將本查詢中的IN謂詞用比較運算符‘=’來代替:
SELECT Sno, Sname, Sdept
FROM Student
WHERE Sdept = (SELECT SdeptFROM StudentWHERE Sname = '劉晨'); /* 解法二*/```
也可以使用自身連接完成以上查詢:
```sql
SELECT s1.Sno, s1.Sname, s1.Sdept
FROM Student s1, Student s2
WHERE s1.Sdept = S2.Sdept AND s2.Sname = '劉晨'; /* 解法三*/
還可以使用EXISTS謂詞完成本查詢:
SELECT Sno, Sname, Sdept
FROM Student S1
WHERE EXISTS(SELECT *FROM Student S2WHERE S2.Sdept=S1.Sdept AND S2.Sname='劉晨'); /* 解法四*/
又如:查詢選修了課程名為“信息系統(tǒng)”的學(xué)生號和姓名。
SELECT Sno, Sname
FROM Student
WHERE Sno IN (SELECT SnoFROM SCWHERE Cno IN(SELECT CnoFROM CourseWHERE Cname = '信息系統(tǒng)'));```
也可以使用連接查詢來完成上述查詢:
```sql
SELECT Student.Sno, Sname
FROM Student, SC, Course
WHERE Student.Sno = SC.Sno ANDSC.Cno = Course.Cno ANDCourse.Cname = '信息系統(tǒng)';
(6)嵌套查詢(帶有比較運算符的子查詢)
例如:找出每個學(xué)生超過他所選修課程平均成績的課程號。
SELECT Sno, Cno
FROM SC x
WHERE Grade >= ( SELECT AVG(Grade)FROM SC yWHERE y.Sno = x.Sno);
(7)嵌套查詢(帶有ANY或ALL謂詞的子查詢)
例如:查詢其他系中比計算機系某個學(xué)生年齡小的學(xué)生的姓名和年齡。
SELECT Sname, Sage
FROM Student
WHERE Sage <ANY (SELECT SageFROM StudentWHERE Sdept = 'CS')AND Sdept <> 'CS';
本查詢也可以使用聚集函數(shù)來實現(xiàn):
SELECT Sname, Sage
FROM Student
WHERE Sage < (SELECT MAX(Sage)FROM StudentWHERE Sdept = 'CS')AND Sdept <> 'CS';
又如:查詢其他系中比計算機系所有學(xué)生年齡都小的學(xué)生的姓名和年齡。
SELECT Sname, Sage
FROM Student
WHERE Sage <ALL (SELECT SageFROM StudentWHERE Sdept = 'CS')AND Sdept <> 'CS';
也可以使用聚集函數(shù)來實現(xiàn):
SELECT Sname, Sage
FROM Student
WHERE Sage < (SELECT MIN(Sage)FROM StudentWHERE Sdept = 'CS')AND Sdept <> 'CS';
(8)嵌套查詢(帶有EXISTS謂詞的子查詢)
例如:查詢所有選修了1號課程的學(xué)生姓名。
111sqlSELECT Sname
FROM Student
WHERE EXISTS
(SELECT *
FROM SC
WHERE Sno=Student.Sno AND Cno=‘1’);
又如:查詢所有未選修1號課程的學(xué)生姓名。
```sql
SELECT Sname
FROM Student
WHERE NOT EXISTS(SELECT *FROM SCWHERE Sno=Student.Sno AND Cno='1');
可以使用帶有EXISTS謂詞的子查詢實現(xiàn)全稱量詞或蘊涵邏輯運算功能:
例如:查詢選修了全部課程的學(xué)生姓名。
SELECT Sname
FROM Student
WHERE NOT EXISTS(SELECT *FROM CourseWHERE NOT EXISTS(SELECT *FROM SCWHERE Sno=Student.Sno ANDCno=Course.Cno));
又如:查詢至少選修了學(xué)生200215122選修的全部課程的學(xué)生號碼。
SELECT DISTINCT Sno
FROM SC SCX
WHERE NOT EXISTS(SELECT *FROM SC SCYWHERE SCY.Sno='200215122' ANDNOT EXISTS(SELECT *FROM SC SCZWHERE SCZ.Sno=SCX.Sno ANDSCZ.Cno=SCY.Cno));
(9)集合查詢
例如:查詢計算機系的學(xué)生以及年齡不大于19歲的的學(xué)生。
SELECT *
FROM Student
WHERE Sdept='CS'
UNION /*并集運算*/
SELECT *
FROM Student
WHERE Sage<=19;
可以改用多重條件查詢:
SELECT *
FROM Student
WHERE Sdept='CS' OR Sage<=19;
又如:查詢既選修了課程1又選修了課程2的學(xué)生(交集運算)。
SELECT Sno
FROM SC
WHERE Cno='1'
INTERSECT /*交集運算*/
SELECT Sno
FROM SC
WHERE Cno='2';
可以使用嵌套查詢:
SELECT Sno
FROM SC
WHERE Cno='1' AND Sno IN(SELECT SnoFROM SCWHERE Cno='2');
思考:能不能改用多重條件查詢?
SELECT Sno
FROM SC
WHERE Cno='1' AND Cno='2';
再如:查詢計算機系的學(xué)生與年齡不大于19歲的學(xué)生的差集。
SELECT *
FROM Student
WHERE Sdept='CS'
EXCEPT /*差集運算*/
SELECT *
FROM Student
WHERE Sage<=19;
可以改用多重條件查詢:
SELECT *
FROM Student
WHERE Sdept='CS' AND Sage>19;
結(jié)果示意