SQL經(jīng)典練習(xí)(7~10)

  1. 查詢沒有學(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é)果
  1. 查詢至少有一門課與學(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é)果一致

  1. 查詢和" 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é)果
  1. 查詢沒學(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é)果
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容