-
查詢沒有學(xué)全所有課程的同學(xué)的信息
??分析:課程表總一共有3個(gè)課程,分別是01語文,02數(shù)學(xué),03英語。存在有的同學(xué)只學(xué)了其中兩門或者一門的課程的情況。想到用聚集函數(shù)COUNT對成績表分組之后的行數(shù)記錄,小于3的就是沒有學(xué)全所有課程的,再根據(jù)查詢出的學(xué)號(hào)在學(xué)生表中查找出詳細(xì)信息。
方法一(子查詢):
SELECT s.*
FROM students s
WHERE s.`S#` IN (SELECT `S#`
FROM SC
GROUP BY `S#`
HAVING COUNT(*)<3);
方法二(聯(lián)結(jié)表):
SELECT s.*
FROM students s,(SELECT `S#` FROM SC GROUP BY `S#` HAVING COUNT(*)<3) AS t
WHERE s.`S#` = t.`S#`;

查詢結(jié)果
-
查詢至少有一門課與學(xué)號(hào)為" 01 "的同學(xué)所學(xué)相同的同學(xué)的信息
??分析:問題分解,首先在成績表中查詢出01號(hào)同學(xué)所學(xué)的課程編號(hào),其次在成績表中,查出包含在01號(hào)同學(xué)課程編號(hào)中的學(xué)生編號(hào),最后,再利用學(xué)生編號(hào)在學(xué)生信息表中返回學(xué)生的詳細(xì)信息。因此嵌套兩層子查詢。
方法一(子查詢):
SELECT s.*
FROM students s
WHERE s.`S#` IN (SELECT `S#`
FROM SC
WHERE `C#` IN (SELECT `C#`
FROM SC
WHERE `S#` = '01'));

查詢結(jié)果
方法二(自聯(lián)結(jié)):
??分析:最開始兩步查詢都是在成績表進(jìn)行的,讓我想起了表的“自聯(lián)結(jié)”,就是復(fù)制一張與自身相同的表,把它當(dāng)做另外一張表,再利用聯(lián)結(jié)條件聯(lián)結(jié),這里要注意用別名將兩個(gè)表區(qū)別開,不然系統(tǒng)就會(huì)因?yàn)闊o法判斷列的歸屬導(dǎo)致報(bào)錯(cuò)。
SELECT s.*
FROM students s
WHERE s.`S#` IN (SELECT p1.`S#`
FROM SC p1,SC p2
WHERE p1.`C#` = p2.`C#`AND p2.`S#` = '01');
??上面代碼中給SC表分別起了兩個(gè)別名p1和p2,相當(dāng)于復(fù)制了一個(gè)相同的表,它們之間利用課程編號(hào)聯(lián)結(jié),在p2表中給出過濾條件,從p1表中查詢出所需要的學(xué)生編號(hào)。得出的結(jié)果是一致的。
注:由于聯(lián)結(jié)查詢比子查詢速度更快,使得查詢性能提高,因此能使用聯(lián)結(jié)盡量使用。

結(jié)果一致
-
查詢和" 01 "號(hào)的同學(xué)學(xué)習(xí)的課程完全相同的其他同學(xué)的信息
??分析:已知01號(hào)同學(xué)三門課程(01,02,03)都學(xué)習(xí)了,因此只要從其他同學(xué)中找出(至少)同時(shí)學(xué)了這三門課程的同學(xué)編號(hào)。(這里用“至少”是考慮到其他同學(xué)有可能不但學(xué)了這三門課程,還學(xué)習(xí)了其他課程,但其實(shí)我們只要保證這三門課程都學(xué)習(xí)了,就滿足題目要求。如果把題目要求理解成不多也不少的也學(xué)了這三門課程,那還要加上一個(gè)篩選條件,比如學(xué)習(xí)的課程數(shù)等于3。)
??把課程表中學(xué)過01課程,02課程,03課程的分別建立虛擬表,這三個(gè)表中,有些同學(xué)三門課程都學(xué)習(xí)了,有些同學(xué)只學(xué)習(xí)了兩門,甚至只學(xué)習(xí)了一門,如果用學(xué)號(hào)將三表聯(lián)結(jié),得出的新表(虛擬表)就是三門課程都學(xué)習(xí)過的學(xué)生。因此
SELECT s.*
FROM students AS s
WHERE `S#` IN (SELECT SC_01.`S#`
FROM (SELECT `S#` FROM SC WHERE `C#` = '01')AS SC_01,
(SELECT `S#` FROM SC WHERE `C#` = '02')AS SC_02,
(SELECT `S#` FROM SC WHERE `C#` = '03')AS SC_03
WHERE SC_01.`S#` = SC_02.`S#` AND SC_02.`S#` = SC_03.`S#`)
AND `S#` <> '01';

查詢結(jié)果
-
查詢沒學(xué)過"張三"老師講授的任一門課程的學(xué)生姓名
??分析:其中一個(gè)一般想到用IN,包含在其中。任意一個(gè)都沒有,就要用NOT IN,可利用子查詢,也可利用表聯(lián)結(jié)查詢。
SELECT s.Sname
FROM students AS s
WHERE s.`S#` NOT IN (SELECT SC.`S#`
FROM SC,courses,teachers AS t
WHERE t.`T#` = courses.`T#` AND courses.`C#` = SC.`C#` AND t.Tname = "張三");

查詢結(jié)果