1、查詢選修了課程的學(xué)生的學(xué)號(hào)。(DISTINCT)
select distinct sno from SC;

查詢結(jié)果
2、查詢選修C1或C2且分?jǐn)?shù)大于等于85分學(xué)生的學(xué)號(hào)、課程號(hào)和成績(jī)。
# 邏輯運(yùn)算符的優(yōu)先級(jí)由高到低為:NOT、AND、OR,可以使用括號(hào)改變優(yōu)先級(jí)。
select sno, cno, score from SC
where (cno = 'C1' or cno = 'C2') and (score >= 85);

查詢結(jié)果
3、查詢工資在1000元~1500元之間的教師的教師號(hào)、姓名及職稱。(BETWEEN...AND... 包含等號(hào))
select tno, tn, prof from T
where sal between 1000 and 1500;
# 等價(jià)于:
select tno, tn, prof from T
where sal >= 1000 and sal <= 1500;

查詢結(jié)果
4、查詢工資不在1000元~1500元間的教師的教師號(hào)、姓名及職稱。(NOT BETWEEN...AND...)
select tno, tn, prof from T
where sal not between 1000 and 1500;

查詢結(jié)果
5、查詢選修C1或C2的學(xué)生的學(xué)號(hào)、課程號(hào)和成績(jī)。(IN/OR)
select sno, cno, score from SC
where cno in('C1', 'C2');
# 也可使用邏輯運(yùn)算符 OR 實(shí)現(xiàn)
select sno, cno, score from SC
where cno = 'C1' or cno = 'C2';

查詢結(jié)果
6、查詢沒有選修C1,也沒有選修C2的學(xué)生的學(xué)號(hào)、課程號(hào)和成績(jī)。(NOT IN)
select sno, cno, score from SC
where sno not in (select sno from SC where cno in('C1', 'C2'));

查詢結(jié)果
7、查詢姓名中第二個(gè)漢字是“力”的教師號(hào)和姓名。
# 通配符:"%"代表0個(gè)或多個(gè)字符,"_"代表一個(gè)字符,"[]"代表在某一范圍的字符,"[^]"代表不在某一范圍的字符。
select tno, tn from T
where tn like '_力%';

查詢結(jié)果
8、查詢沒有考試成績(jī)的學(xué)生的學(xué)號(hào)和相應(yīng)的課程號(hào)。(空值:NULL)
# 某個(gè)字段沒有值稱為空值(NULL)??罩挡煌诹愫涂崭?,它不占任何存儲(chǔ)空間。
select sno, cno from SC
where score is null;

查詢結(jié)果
9、求學(xué)號(hào)為S1的學(xué)生的總分和平均分。(SUM、AVG)
# 函數(shù)SUM和AVG只能對(duì)數(shù)值型字段進(jìn)行計(jì)算。保留兩位小數(shù):ROUND(avg(score),2)
select sum(score), avg(score) from SC
where sno = 'S1';

查詢結(jié)果
10、求選修C1號(hào)課程的最高分、最低分及之間相差的分?jǐn)?shù)。(MAX、MIN)
select max(score), min(score), max(score)-min(score) as diff_score from SC
where cno = 'C1';

查詢結(jié)果
11、求計(jì)算機(jī)系學(xué)生的總數(shù)。(COUNT)
# COUNT(*)用來統(tǒng)計(jì)元組的個(gè)數(shù),不消除重復(fù)行,不允許使用DISTINCT。
select count(sno) from S
where dept = '計(jì)算機(jī)';

查詢結(jié)果
12、求學(xué)校中共有多少個(gè)系。(DISTINCT)
# COUNT 函數(shù)對(duì)空值不計(jì)算,但對(duì)0計(jì)算。
select count(distinct dept) from S;

查詢結(jié)果
13、統(tǒng)計(jì)有成績(jī)同學(xué)的人數(shù)。
select count(distinct sno) from SC
where score is not null;

查詢結(jié)果
14、查詢各個(gè)教師的教師號(hào)及其任課的門數(shù)。(GROUP BY)
select tno, count(cno) from TC
group by tno;

查詢結(jié)果
15、查詢選修兩門以上(含兩門)課程的學(xué)生的學(xué)號(hào)和選課門數(shù)。(GROUP BY...HAVING...)
# 當(dāng)在一個(gè)SQL查詢中同時(shí)使用WHERE子句,GROUP BY子句和HAVING子句時(shí),其順序是:WHERE、GROUP BY、HAVING。
# WHERE與HAVING子句的根本區(qū)別在于作用對(duì)象不同。
# WHERE子句作用于基本表或視圖,從中選擇滿足條件的元組;HAVING子句作用于組,選擇滿足條件的組,必須用在GROUP BY子句之后。
select sno, count(cno) from SC
group by sno
having count(cno) >= 2;

查詢結(jié)果
16、查詢選修C1的學(xué)生學(xué)號(hào)和成績(jī),并按成績(jī)降序排列。(ORDER BY...DESC降序/ASC升序,缺省時(shí)為升序)
select sno, score from SC
where cno = 'C1'
order by score desc;

查詢結(jié)果
17、查詢選修C2,C3,C4或C5課程的學(xué)號(hào)、課程號(hào)和成績(jī),查詢結(jié)果按學(xué)號(hào)升序排列,學(xué)號(hào)相同再按成績(jī)降序排列。(ORDER BY...DESC降序/ASC升序,缺省時(shí)為升序)
select sno, cno, score from SC
where cno in ('C2', 'C3', 'C4', 'C5')
order by sno, score desc;

查詢結(jié)果
18、查詢“劉偉”老師所講授的課程,要求列出教師號(hào)、教師姓名和課程號(hào)。(INNER JOIN...ON...)
# 當(dāng)將JOIN關(guān)鍵字放于FROM子句中時(shí),應(yīng)有關(guān)鍵字ON與之對(duì)應(yīng),以表明連接的條件。
# 引用列名Tno時(shí)要加上表名前綴,這是因?yàn)閮蓚€(gè)表中的列名相同,必須用表名前綴來確切說明所指列屬于哪個(gè)表,以避免二義性。如果列名是唯一的(如Tn)就不必加前綴。
select T.tno, tn, cno
from T inner join TC on T.tno = TC.tno
where tn = '劉偉';
# 方法2:
select T.tno, tn, cno from T, TC
where T.tno = TC.tno and tn = '劉偉';

查詢結(jié)果
19、查詢所有選課學(xué)生的學(xué)號(hào)、姓名、選課名稱及成績(jī)。(當(dāng)有兩個(gè)以上的表進(jìn)行連接時(shí),稱為多表連接。)
select S.sno, sn, cn, score from S, C, SC
where S.sno = SC.sno and SC.cno = C.cno

查詢結(jié)果
20、查詢每門課程的課程號(hào)、課程名和選課人數(shù)。(GROUP BY)
select C.cno, cn, count(sno) from C, SC
where C.cno = SC.cno
group by cno;

查詢結(jié)果
21、查詢所有學(xué)生的學(xué)號(hào)、姓名、選課名稱及成績(jī)(沒有選課的同學(xué)的選課信息顯示為空)。(LEFT JOIN...ON...)
# 在外部連接中,參與連接的表有主從之分,以主表的每行數(shù)據(jù)去匹配從表的數(shù)據(jù)列。
# 符合連接條件的數(shù)據(jù)將直接返回到結(jié)果集中;對(duì)那些不符合連接條件的列,將被填上NULL值后,再返回到結(jié)果集中。
# (由于bit數(shù)據(jù)類型不允許有NULL值,因此對(duì)bit類型的列將會(huì)被填上0值,再返回到結(jié)果中。)
select S.sno, sn, cn, score
from S left join SC on S.sno = SC.sno left join C on SC.cno = C.cno

查詢結(jié)果
22、查詢所有比“劉偉”工資高的教師姓名、工資和劉偉的工資。(自連接查詢)
# 當(dāng)一個(gè)表與其自身進(jìn)行連接操作時(shí),稱為表的自身連接。
# 本題將T表起兩個(gè)別名分別為T1和T2,將T1、T2中滿足比劉偉工資高的行連接起來。這實(shí)際上時(shí)同一表T的大于連接。
select T1.tn, T1.sal as sal1, T2.sal as sal2 from T as T1, T as T2
where T1.sal > T2.sal and T2.tn = '劉偉';
# 方法2:
select T1.tn, T1.sal as sal1, T2.sal as sal2
from T as T1 inner join T as T2 on T1.sal > T2.sal
where T2.tn = '劉偉';

查詢結(jié)果
23、檢索所有學(xué)生姓名,年齡和選課名稱。
select sn, age, cn from S, C, SC
where S.sno = SC.sno and C.cno = SC.cno

查詢結(jié)果
24、查詢與“劉偉”老師職稱相同的教師號(hào)、姓名。(返回一個(gè)值的普通子查詢)
# 在WHERE子句中包含一個(gè)形如SELECT-FROM-WHERE的查詢塊,此查詢稱為子查詢或嵌套查詢,包含子查詢的語(yǔ)句稱為父查詢或外部查詢。
# 嵌套查詢?cè)趫?zhí)行時(shí)由里向外處理,每個(gè)子查詢是在上一級(jí)外部查詢處理之前完成的,父查詢要用到子查詢的結(jié)果。
# 普通子查詢的執(zhí)行順序是:首先執(zhí)行子查詢,然后把子查詢的結(jié)果作為父查詢的查詢條件的值。
# 普通子查詢只執(zhí)行一次,而父查詢所涉及的所有記錄行都與其查詢結(jié)果進(jìn)行比較以確定查詢結(jié)果集。
# 當(dāng)子查詢的返回值只有一個(gè)時(shí),可以使用比較運(yùn)算符(=、>、<、>=、<=、!=)將父查詢和子查詢連接起來。
select tno, tn from T
where prof = (select prof from T where tn = '劉偉');

查詢結(jié)果
25、查詢講授課程號(hào)為C5的教師姓名。(返回一組值的普通子查詢:ANY 任意一個(gè))
# 如果子查詢的返回值不止一個(gè),而是一個(gè)集合時(shí),則不能直接使用比較運(yùn)算符,可以在比較運(yùn)算符和子查詢之間插入ANY或ALL。
select tn from T
where tno = ANY (select tno from TC where cno = 'C5');
# 可以使用連接操作來實(shí)現(xiàn),具體可根據(jù)自己學(xué)習(xí)習(xí)慣任意選用。
select tn from T, TC
where T.tno = TC.tno and cno = 'C5';

查詢結(jié)果
26、查詢其他系中比計(jì)算機(jī)系某一教師工資高的教師的姓名和工資。(返回一組值的普通子查詢:ANY 任意一個(gè))
select tn, sal from T
where (sal > ANY (select sal from T where dept = '計(jì)算機(jī)')) and (dept <> '計(jì)算機(jī)'); # "<>"表示不等于
# 方法2:利用庫(kù)函數(shù)MIN找到計(jì)算機(jī)系中所有教師的最低工資
select tn, sal from T
where sal > (select min(sal) from T where dept = '計(jì)算機(jī)') and dept != '計(jì)算機(jī)'; # "!="表示不等于

查詢結(jié)果
27、查詢講授課程號(hào)為C5的教師姓名(使用IN)。(可以使用IN代替"=ANY")
select tn from T
where tno in (select tno from TC where cno = 'C5');

查詢結(jié)果
28、查詢其他系中比計(jì)算機(jī)系所有教師工資都高的教師的姓名和工資。(返回一組值的普通子查詢:ALL 全部)
select tn, sal from T
where (sal > All (select sal from T where dept = '計(jì)算機(jī)')) and (dept <> '計(jì)算機(jī)'); # "<>"表示不等于
# 方法2:利用庫(kù)函數(shù)MAX找到計(jì)算機(jī)系中所有教師的最高工資
select tn, sal from T
where sal > (select max(sal) from T where dept = '計(jì)算機(jī)') and dept != '計(jì)算機(jī)'; # "!="表示不等于

查詢結(jié)果
29、查詢不講授課程號(hào)為C5的教師姓名。(相關(guān)子查詢)
# 子查詢的查詢條件需要引用父查詢表中的屬性值,這類查詢稱為相關(guān)子查詢。
# 相關(guān)子查詢的執(zhí)行順序是:首先選取父查詢表中第一行記錄,內(nèi)部的子查詢利用此行中相關(guān)的屬性值進(jìn)行查詢,然后父查詢根據(jù)子查詢返回的結(jié)果判斷此行是否滿足查詢條件。
# 如果滿足條件,則把該行放入父查詢的查詢結(jié)果集合中。重復(fù)執(zhí)行這一過程,直到處理完父查詢表中的每一行數(shù)據(jù)。
# 由此可見,相關(guān)子查詢的執(zhí)行次數(shù)是由父查詢表的行數(shù)決定的。
select distinct tn from T
where 'C5' <> All (select cno from TC where tno = T.tno); # 子查詢解析:select cno from tc where tno='T1';其中tno的值由父查詢表中數(shù)據(jù)決定
# "<>ALL"表示不等于子查詢結(jié)果中的任意一個(gè)值,也可以用NOT IN代替。
select distinct tn from T
where 'C5' not in (select cno from TC where tno = T.tno);

查詢結(jié)果
30、用含有EXISTS的語(yǔ)句完成第25題的查詢,即查詢講授課程號(hào)為C5的教師姓名。(相關(guān)子查詢:EXISTS)
# EXISTS是表示存在的量詞,帶有EXISTS的子查詢不返回任何實(shí)際數(shù)據(jù),它只得到邏輯值"真"或"假"。
# 當(dāng)子查詢的查詢結(jié)果集合為 非空 時(shí),外層的WHERE子句返回真值,否則返回假值。
# 此題當(dāng)子查詢TC表存在一行記錄滿足其WHERE子句中的條件時(shí),父查詢便得到一個(gè)TN值,重復(fù)執(zhí)行以上過程,直到得出最后結(jié)果。
select tn from T
where EXISTS (select * from TC where tno = T.tno and cno = 'C5');

查詢結(jié)果
31、查詢沒有講授課程號(hào)為C5的教師姓名。(相關(guān)子查詢:NOT EXISTS)
# NOT EXISTS:當(dāng)子查詢的查詢結(jié)果 為空 時(shí),外層的WHERE子句返回真值,否則返回假值。
select tn from T
where NOT EXISTS (select * from TC where tno = T.tno and cno = 'C5');

查詢結(jié)果
32、查詢選修所有課程的學(xué)生姓名。(相關(guān)子查詢:NOT EXISTS)
# 此題可以理解為:選出這樣一些學(xué)生名單,在SC表中不存在他們沒有選修課程的記錄。
select sn from S
where NOT EXISTS (select * from C where NOT EXISTS ( select * from SC where sno = S.sno and cno = C.cno));
# 方法2:
select sn from S, SC
where S.sno = SC.sno
group by S.sno
having count(distinct SC.cno) = (select count(cno) from C);

查詢結(jié)果
33、從SC數(shù)據(jù)表中查詢出學(xué)號(hào)為“S1”同學(xué)的學(xué)號(hào)和總分,再?gòu)腟C數(shù)據(jù)表中查詢出學(xué)號(hào)為“S5”的同學(xué)的學(xué)號(hào)和總分,然后將兩個(gè)查詢結(jié)果合并成一個(gè)結(jié)果集。(UNION)
# 合并查詢時(shí)使用UNION操作符將來自不同查詢的數(shù)據(jù)組合起來,形成一個(gè)具有綜合信息的查詢結(jié)果。
# UNION操作會(huì)自動(dòng)將重復(fù)的數(shù)據(jù)行剔除。
# 必須注意的是:參加合并查詢的各子查詢的使用的表結(jié)構(gòu)應(yīng)該相同,即各子查詢中的數(shù)據(jù)數(shù)目和對(duì)應(yīng)的數(shù)據(jù)類型都必須相同。
select sno, sum(score) from SC where sno = 'S1'
UNION
select sno, sum(score) from SC where sno = 'S5'
group by sno;

查詢結(jié)果
34、從SC數(shù)據(jù)表中查詢出所有同學(xué)的學(xué)號(hào)和總分,并將查詢結(jié)果存放到一個(gè)新的數(shù)據(jù)表Cal_Table中。(SELECT...INTO...)
# 使用SELECT...INTO...語(yǔ)句可以將查詢結(jié)果存儲(chǔ)到一個(gè)新建的數(shù)據(jù)庫(kù)表或臨時(shí)表。
# 臨時(shí)表只存儲(chǔ)在內(nèi)存中,并不存儲(chǔ)在數(shù)據(jù)庫(kù)中,所以其存在的時(shí)間非常短。
select sno, sum(score) into Cal_Table
from SC
group by sno;
35、在S表中添加一條學(xué)生記錄(學(xué)號(hào):S7,姓名:鄭冬,性別:女,年齡:21,系別:計(jì)算機(jī))。(添加一行新紀(jì)錄:INSERT INTO)
# 列名的排列順序不一定要和表定義時(shí)的順序一致,但當(dāng)指定列名時(shí),VALUES子句中值的排列順序必須和列名表中的列名排列順序一致,個(gè)數(shù)相等,數(shù)據(jù)類型一一對(duì)應(yīng)。
# 必須用逗號(hào)將各個(gè)數(shù)據(jù)分開,字符型數(shù)據(jù)要用單引號(hào)括起來。
insert into S (sno, sn, sex, age, dept)
values ('S7', '鄭冬', '女', 21, '計(jì)算機(jī)');
# 如果INTO子句中沒有指定列名,則新添加的記錄必須在每個(gè)屬性列上均有值,且VALUES子句中值的排列順序要和表中各屬性列的排列順序一致。
insert into S
values ('S7', '鄭冬', '女', 21, '計(jì)算機(jī)');
36、在SC表中添加一條選課記錄('S7', 'C1')。(添加一行記錄的部分?jǐn)?shù)據(jù)值:INSERT INTO)
# 將VALUES子句中的值按照INTO子句中指定列名的順序添加到表中,對(duì)于INTO子句中沒有出現(xiàn)的列,則新添加的記錄在這些列上將賦NULL值。
# 如果在表定義時(shí)有NOT NULL約束的屬性列不能取NULL值,插入時(shí)必須給其賦值。
insert into SC (sno, cno)
values ('S7', 'C1'); # score將被賦NULL值
37、求出各系教師的平均工資,把結(jié)果存放在新表AvgSal中。(用子查詢添加多行記錄)
# 添加多行記錄用于表間的復(fù)制,即將一個(gè)表中的數(shù)據(jù)抽取數(shù)行添加到另一個(gè)表中,可以通過子查詢來實(shí)現(xiàn)。
# INSERT INTO <表名> [(<列名1>[,<列名2>…])] 子查詢
# 首先,建立新表AvgSal,用來存放系名和各系的平均工資。
create table AvgSal (
Department Varchar(20),
Average Smallint
);
# 然后,利用子查詢求出T表中各系的平均工資,把結(jié)果存放在新表AvgSal中。
insert into AvgSal
select dept, avg(sal) from T group by dept;
38、把劉偉老師轉(zhuǎn)到信息系。(修改一行數(shù)據(jù))
# SET子句給出要修改的列及其修改后的值,WHERE子句指定待修改的記錄應(yīng)當(dāng)滿足的條件,WHERE子句省略時(shí),則修改表中的所有記錄。
# UPDATE <表名> SET <列名>=<表達(dá)式> [,<列名>=<表達(dá)式>]… [WHERE <條件>]
update T set dept = '信息'
where tn = '劉偉';
39、將所有學(xué)生的年齡增加1歲。(修改多行數(shù)據(jù))
update S set age = age + 1;
40、把教師表中工資小于或等于1000元的講師的工資提高20%。(修改多行數(shù)據(jù))
update T set sal = sal * 1.2
where prof = '講師' and sal <= 1000;
41、把講授C5課程的教師的崗位津貼增加100元。(用子查詢選擇要修改的行)
update T set comm = comm + 100
where tno in (select T.tno from T, TC where T.tno = TC.tno and cno = 'C5'); # 子查詢的作用是得到講授C5課程的教師號(hào)
42、把所有教師的工資提高到平均工資的1.2倍。(用子查詢提供要修改的值)
update T set sal = (select avg(sal) * 1.2 from T); # 子查詢的作用是得到所有教師的平均工資的1.2倍
43、刪除劉偉老師的記錄。(刪除一行數(shù)據(jù))
# WHERE子句指定待刪除的記錄應(yīng)當(dāng)滿足的條件,WHERE子句省略時(shí),則刪除表中的所有記錄。
# DELETE FROM <表名> [WHERE <條件>]
delete from T
where tn = '劉偉';
44、刪除劉偉老師授課的記錄。(利用子查詢選擇要?jiǎng)h除的行)
delete from TC
where tno = (select tno from T where tn = '劉偉');