【DataBase】SQL50 Training 50題訓練
阿新 • • 發佈:2020-07-26
原文地址:
https://blog.csdn.net/xiushuiguande/article/details/79476964
實驗資料
CREATE DATABASE IF NOT EXISTS SQL50; USE SQL50;
CREATE TABLE Student(sid VARCHAR(10),sname VARCHAR(10),sage DATETIME,ssex NVARCHAR(10)); INSERT INTO Student VALUES('01' , '趙雷' , '1990-01-01' , '男'); INSERT INTO Student VALUES('02' , '錢電' , '1990-12-21' , '男'); INSERT INTO Student VALUES('03' , '孫風' , '1990-05-20' , '男'); INSERT INTO Student VALUES('04' , '李雲' , '1990-08-06' , '男'); INSERT INTO Student VALUES('05' , '周梅' , '1991-12-01' , '女'); INSERT INTO Student VALUES('06' , '吳蘭' , '1992-03-01' , '女'); INSERT INTO Student VALUES('07' , '鄭竹' , '1989-07-01' , '女'); INSERT INTO Student VALUES('08' , '王菊' , '1990-01-20' , '女');
CREATE TABLE Course(cid VARCHAR(10),cname VARCHAR(10),tid VARCHAR(10)); INSERT INTO Course VALUES('01' , '語文' , '02'); INSERT INTO Course VALUES('02' , '數學' , '01'); INSERT INTO Course VALUES('03' , '英語' , '03');
CREATE TABLE Teacher(tid VARCHAR(10),tname VARCHAR(10)); INSERT INTO Teacher VALUES('01' , '張三'); INSERT INTO Teacher VALUES('02' , '李四'); INSERT INTO Teacher VALUES('03' , '王五');
CREATE TABLE SC(sid VARCHAR(10),cid VARCHAR(10),score DECIMAL(18,1)); INSERT INTO SC VALUES('01' , '01' , 80); INSERT INTO SC VALUES('01' , '02' , 90); INSERT INTO SC VALUES('01' , '03' , 99); INSERT INTO SC VALUES('02' , '01' , 70); INSERT INTO SC VALUES('02' , '02' , 60); INSERT INTO SC VALUES('02' , '03' , 80); INSERT INTO SC VALUES('03' , '01' , 80); INSERT INTO SC VALUES('03' , '02' , 80); INSERT INTO SC VALUES('03' , '03' , 80); INSERT INTO SC VALUES('04' , '01' , 50); INSERT INTO SC VALUES('04' , '02' , 30); INSERT INTO SC VALUES('04' , '03' , 20); INSERT INTO SC VALUES('05' , '01' , 76); INSERT INTO SC VALUES('05' , '02' , 87); INSERT INTO SC VALUES('06' , '01' , 31); INSERT INTO SC VALUES('06' , '03' , 34); INSERT INTO SC VALUES('07' , '02' , 89); INSERT INTO SC VALUES('07' , '03' , 98);
4張表的結構關係
Course課程表:
課程ID、課程名、教師ID
SC成績表:
學生ID、課程ID、成績
Student學生表:
學生ID、學生姓名、學生年齡、學生性別、
Teacher老師表:
教師ID、教師名
1、查詢“01”課程比“02”課程成績高的所有學生的學號
先查詢 01課程的成績表 & 02課程的成績表
SELECT * FROM `sc` WHERE `cid` = 1; SELECT * FROM `sc` WHERE `cid` = 2;
使用連線查詢,附加 01表的成績 > 02表的成績
SELECT sc1.`sid` FROM (SELECT `sid`,`cid`,`score` FROM `sc` WHERE `cid` = 1) AS sc1, (SELECT `sid`,`cid`,`score` FROM `sc` WHERE `cid` = 2) AS sc2 where sc1.`sid` = sc2.`sid` and sc1.`score` > sc2.`score`;
2、查詢平均成績大於60分的同學的學號和平均成績
資訊都在成績表裡面,要每個學生的全部成績的平均成績,
使用AVG聚合函式,然後對學生ID進行分組GROUP BY
查出上面的結果之後再對平均分進行 > 60的篩選
但是為什麼SQL查不出結果???
SELECT `sid`,AVG(`score`) AS 'avg_sc' FROM `sc` GROUP BY `sid` HAVING 'avg_sc' > 60;
3、查詢所有同學的學號、姓名、選課數、總成績
因為在成績表裡面,可以使用分組+計數+求和,求出成績表內的學號,選課數和總成績
然後再和學生表進行一個左連線,學生表作為主表,上面的結果表作為從表,因為還存在學生表沒有選課的情況
成績表的篩選
SELECT `sid`,COUNT(`cid`) AS '選課數',SUM(`score`) as '總成績' FROM `sc` GROUP BY `sid`;
左連線學生表
SELECT S1.`sid`,S1.`sname`,S2.選課數,S2.總成績 FROM `student` AS S1 LEFT JOIN ( SELECT `sid`,COUNT(`cid`) AS '選課數',SUM(`score`) AS '總成績' FROM `sc`
GROUP BY `sid`) AS S2 ON S1.`sid` = S2.`sid`;
4、查詢姓“李”的老師的個數
只在李老師表內查詢,使用計數函式
SELECT COUNT(*) FROM `teacher` WHERE `tname` LIKE '李%';
5、查詢沒學過“張三”老師課的同學的學號、姓名;
先篩選張三老師教授的課程ID,可以看到是01課程
SELECT `tid` FROM `teacher` WHERE `tname` = '張三';
通過上面的線索,查詢課程表,其對應的課程ID是02
select `cid` -- ,`cname`,`tid` from `course` where `tid` = (SELECT `tid` FROM `teacher` WHERE `tname` = '張三');
在成績表查詢沒學02課程太難排查了,所以反過來,我們查學了02的學生ID
-- 我們查詢學了該課程的學生ID SELECT DISTINCT `sid` FROM `sc` WHERE `cid` = (SELECT `cid` FROM `course` WHERE `tid` = (SELECT `tid` FROM `teacher` WHERE `tname` = '張三'))
再用上面這張表連線學生表查詢【左連線】
SELECT S1.`sid`,S1.`sname` FROM `student` AS S1 LEFT JOIN (SELECT DISTINCT `sid` FROM `sc` WHERE `cid` = (SELECT `cid` FROM `course` WHERE `tid` = (SELECT `tid` FROM `teacher` WHERE `tname` = '張三'))) AS S2 ON S1.`sid` = S2.`sid` WHERE S1.`sid` NOT IN(S2.`sid`);
6、查詢學過“```”並且也學過編號“```”課程的同學的學號、姓名;
7、查詢學過“張三”老師所教的所有課的同學的學號、姓名;
查詢張三老師的教師編號:
SELECT `tid` FROM `Teacher` WHERE `tname` = '張三'
然後根據編號查詢所授課程:
SELECT `cid` FROM `Course` WHERE `tid` = (SELECT `tid` FROM `Teacher` WHERE `tname` = '張三');
然後得到對應的所學課程的學生編號
SELECT `sid` FROM `SC` WHERE `cid` IN( SELECT `cid` FROM `Course` WHERE `tid` = ( SELECT `tid` FROM `Teacher` WHERE `tname` = '張三' ) );
最後再聯合學生表:
SELECT `sid`,`sname` FROM `Student` WHERE `sid` IN ( select `sid` from `SC` where `cid` IN( SELECT `cid` FROM `Course` WHERE `tid` = ( SELECT `tid` FROM `Teacher` WHERE `tname` = '張三' ) ) );
8、查詢課程編號“01”的成績比課程編號“02”課程低的所有同學的學號、姓名;
9、查詢所有課程成績小於60分的同學的學號、姓名;
也就是說只要其中一個課程成績大於60就不算在內
所以就可以先查詢大於60分,再取反就行了
大於60分的學生ID:
SELECT `sid` FROM `SC` WHERE `score` > 60
然後取反得到:
SELECT `sid`,`sname` FROM `Student` WHERE `sid` NOT IN(SELECT `sid` FROM `SC` WHERE `score` > 60)
10、查詢沒有學全所有課的同學的學號、姓名;
首先是需要知道全部課程個數
然後這個查詢的意思是,計數學生學習課程的個數,如果小於總課數即沒學全
但是需要跟學生表關聯,他這裡的聯動真的難理解。。。
SELECT `sid`,`sname` FROM `Student` WHERE (SELECT COUNT(*) FROM `SC` WHERE `Student`.`sid` = `SC`.`sid`) < (SELECT COUNT(*) FROM `Course`)
11、查詢至少有一門課與學號為“01”的同學所學相同的同學的學號和姓名;
24、查詢學生平均成績及其名次
SELECT a.sid, a.avg_score, SUM(CASE WHEN a.avg_score<b.avg_score THEN 1 ELSE 0 END)+1 scc FROM (SELECT sid,AVG(score) avg_score FROM SC GROUP BY sid) a INNER JOIN (SELECT sid,AVG(score) avg_score FROM SC GROUP BY sid) b GROUP BY a.sid, a.avg_score ORDER BY scc
25、查詢各科成績前三名的記錄
26、查詢每門課程被選修的學生數
SELECT `cid`,COUNT(`sid`) '人數' FROM `sc` GROUP BY `cid`
27、查詢出只選修了一門課程的全部學生的學號和姓名
# 查詢選課數只有1的學生編號 SELECT `sid`,COUNT(`cid`) '選課數' FROM `sc` GROUP BY `sid` HAVING `選課數` = 1 # 然後關聯學生表進行查詢 SELECT `student`.`sname`,`ss`.`sid` FROM `student`, (SELECT `sid`,COUNT(`cid`) '選課數' FROM `sc` GROUP BY `sid` HAVING `選課數` = 1) `ss` WHERE `student`.`sid` IN (`ss`.`sid`)
28、查詢男生、女生人數
SELECT `ssex`,COUNT(1) '人數' FROM `student` GROUP BY `ssex`
29、查詢名字中含有"風"字的學生資訊
SELECT * FROM `student` WHERE `sname` LIKE '%風%';
30、查詢同名同姓學生名單,並統計同名人數
SELECT `sname`,COUNT(1) AS '同名人數' FROM `student` GROUP BY `sname` HAVING `同名人數` > 1
30、查詢同名同性學生名單,並統計同名男生人數
SELECT `sname`,`ssex`, COUNT(1) AS num FROM Student GROUP BY `sname`,`ssex` HAVING COUNT(1) > 1 AND `ssex`='男'
31、查詢1990年出生的學生名單(注:Student表中Sage列的型別是datetime)
SELECT * FROM `student` WHERE YEAR(`sage`) = 1990 ;
32、查詢每門課程的平均成績,結果按平均成績升序排列,平均成績相同時,按課程號降序排列
# 對課程編號分組,求平均分,然後分數升序排列,對課程編號降序排列 SELECT `cid`,AVG(`score`) FROM `sc` GROUP BY `cid` ORDER BY `cid` DESC;
37、查詢不及格的課程,並按課程號從大到小排列
# 在成績表中的查詢 SELECT * FROM `sc` WHERE `score` < 60 ORDER BY `cid` DESC; # 關聯課程表 SELECT `sc`.*, `course`.`cname` FROM `sc`,`course` WHERE `sc`.`cid` = `course`.`cid` AND `sc`.`score` < 60 ORDER BY `sc`.`cid` DESC
38、查詢課程編號為"01"且課程成績在60分以上的學生的學號和姓名;
# 1、現在成績表查詢課程編號為1的 SELECT * FROM `sc` WHERE `cid` = 01; # 2、再新增分數要求大於60的 SELECT * FROM `sc` WHERE `cid` = 01 AND `score` > 60; # 3、最後聯合學生表獲取名字 SELECT `sc`.*,`student`.`sname` FROM `sc`,`student` WHERE `sc`.`sid` = `student`.`sid` AND `sc`.`cid` = 01 AND `score` > 60
40、查詢選修“張三”老師所授課程的學生中,成績最高的學生姓名及其成績
# 查詢老師編號 SELECT `tid` FROM `teacher` WHERE `tname` = '張三'; # 通過編號查詢所授課程編號 SELECT `cid` FROM `course` WHERE `tid` = (SELECT `tid` FROM `teacher` WHERE `tname` = '張三'); # 查詢到成績表學生編號和成績 SELECT `sid`,`score` FROM `sc` WHERE`cid` = (SELECT `cid` FROM `course` WHERE `tid` = (SELECT `tid` FROM `teacher` WHERE `tname` = '張三')) ORDER BY `score` DESC LIMIT 1 # 關聯學生表 SELECT `student`.`sname`,`ss`.`score` FROM `student`, (SELECT `sid`,`score` FROM `sc` WHERE`cid` = (SELECT `cid` FROM `course` WHERE `tid` = (SELECT `tid` FROM `teacher` WHERE `tname` = '張三')) ORDER BY `score` DESC LIMIT 1) `ss` WHERE `student`.`sid` = `ss`.`sid`
42、查詢每門功課成績最好的前兩名學生
43、統計每門課程的學生選修人數(超過5人的課程才統計)。
要求輸出課程號和選修人數,查詢結果按人數降序排列,若人數相同,按課程號升序排列
# 查詢成績表,按照課程欄位分組,計數整個表的記錄 # 要求課程大於5記錄的倒序排序,並返回人數記錄 SELECT cid,COUNT(1) COUNT FROM SC GROUP BY cid HAVING COUNT(1)>=5 ORDER BY COUNT DESC,cid ;
44、檢索至少選修兩門課程的學生學號
# 查詢成績表,並計數課程欄位 # 對學號欄位分組,之後計數的課程欄位大於1的記錄返回 SELECT `sid`,COUNT(`cid`) AS C FROM `sc` GROUP BY `sid` HAVING C > 1;
45、查詢選修了全部課程的學生資訊
# 1 先查詢課程表的總課程數量 SELECT COUNT(1) FROM Course # 2 在成績表中,查詢選課累計等於總課程數的學生ID SELECT sid ,COUNT(cid) count_c FROM SC GROUP BY sid HAVING count_c=(SELECT COUNT(1) FROM Course); # 3 查詢學生表得到資訊 SELECT `student`.* from `student`, (SELECT sid ,COUNT(cid) count_c FROM SC GROUP BY sid HAVING count_c=(SELECT COUNT(1) FROM Course)) as t WHERE `student`.`sid` in (t.`sid`)
46、查詢各學生的年齡
# 用當前日期求得年份值,再減去欄位日期的年份值即可 SELECT Student.*,YEAR(CURDATE())-YEAR(Student.sage) AS '年齡' FROM Student;
47、查詢本週過生日的學生
SELECT * FROM Student WHERE WEEKOFYEAR(NOW())-WEEKOFYEAR(sage)=0;
48、查詢下週過生日的學生
# 使用周按年換算函式,然後和月一樣,下一週就取-1 SELECT * FROM Student WHERE WEEKOFYEAR(NOW())-WEEKOFYEAR(sage)=-1;
49、查詢本月過生日的學生
# 先求出現在的時間的月,再和欄位月相減得為0的記錄即可 SELECT * FROM Student WHERE MONTH(NOW())-MONTH(sage)=0;
50、查詢下月過生日的學生
# 本月值,減去欄位月的值,相差一個月 # 因為本月大於欄位月相減求得的差一定是大於0的 # 所以要查出下一個月過生日的人應該為負數,例如下一個月就-1,下3個月就-3 SELECT * FROM Student WHERE MONTH(NOW())-MONTH(sage)=-1;