50個MySQL練習題
前言
mysql不外乎就是新增、修改、刪除與查詢,四個動作中比較重要大概就是查詢了!要熟練mysql網路上有很多類似50題的題庫與題目,這裡有一種題庫與題目還有自己練習的結果。1~50題我認為每10題難度會增加一點,要練習的話建議從第1題開始!
創建表格
學生表, 教師表, 成績表, 課程表
1 | create table student( |
輸入數據
1 | -- 學生表 |
練習題
- 查詢學生表的 前10條資料
- 查詢成績表所有成績的最低分,平均分,總分
- 查詢老師 “諶燕” 所帶的課程設數量
- 查詢所有老師所帶 的課程 數量
- 查詢姓”張”的學生名單
- 查詢課程名稱為’Oracle’且分數低於60 的學號和分數
- 查詢所有學生的選課 課程名稱
- 查詢任何一門課程成績在70 分以上的學生姓名.課程名稱和分數
- 查詢不及格的課程,並按課程號從大到小排列 學號,課程號,課程名,分數
- 查詢沒學過”諶燕”老師講授的任一門課程的學號,學生姓名
- 查詢兩門以上不及格課程的同學的學號及其平均成績
- 檢索’c004’課程分數小於60,按分數降序排列的同學學號
- 查詢’c001’課程比’c002’課程成績高的所有學生的學號
- 查詢平均成績大於60 分的同學的學號和平均成績
- 查詢所有同學的學號.姓名.選課數.總成績
- 查詢姓”劉”的老師的個數
- 查詢只學”諶燕”老師所教的課的同學的學號:姓名
- 查詢學過”c001″並且也學過編號”c002″課程的同學的學號.姓名
- 查詢學過”諶燕”老師所教的所有課的同學的學號:姓名
- 查詢課程編號”c004″的成績比課程編號”c001″和”c002″課程低的所有同學的學號.姓名
- 查詢所有課程成績小於60 分的同學的學號.姓名
- 查詢沒有學課的同學的學號.姓名
- 查詢與學號為”s001″一起上過課的同學的學號和姓名
- 查詢跟學號為”s005″所修課程完全一樣的同學的學號和姓名
- 查詢各科成績最高和最低的分 顯示:課程ID,最高分,最低分
- 按各科平均成績和及格率的百分數 照平均從低到高顯示
- 查詢每個課程的老師及平均分從高到低顯示 老師名稱,課程名稱,平均分數
- 統計列印各科成績,各分數段人數:課程ID,課程名稱,verygood[100-86], good[85-71], bad[<60]
- 查詢各科成績前三名的記錄:(不考慮成績並列情況)
- 查詢每門課程被選修的學生數
- 查詢出只選修了兩門課程的全部學生的學號和姓名
- 查詢男生.女生人數
32-1. 查詢每個課程的男生女生總數 - 查詢同名同姓學生名單,並統計同名人數
- 查詢年紀最小跟最大的學生名單(注:Student 表中Sage 列的型別是int)
- 查詢每門課程的平均成績,結果按平均成績升序排列,平均成績相同時,按課程號降序排列
- 查詢平均成績大於85 的所有學生的學號.姓名和平均成績
- 查詢課程編號為c001 且課程成績在80 分以上的學生的學號和姓名
- 檢索每課程第二高分的學號 分數(考慮成績並列)
- 求選了課程的學生人數
- 查詢選修”諶燕”老師所授課程的學生中,成績最高的學生姓名及其成績
- 查詢不同課程成績有相同的學生的學號.課程號.學生成績
- 所有課程排名成績(不考慮並列) 學號,課程號,排名,成績 照課程,排名排序
- 所有課程排名成績(考慮並列) 學號,課程號,排名,成績 照課程,排名排序
- 做所有學生顯示學生名稱,課程名稱,成績,老師名稱的視圖
- 查詢上過所有老師教的課程的學生 學號,學生名
- 查詢包含數字的課程名
- 查詢只有英文的課程名
- 查詢所有學生的平均成績 並排名 , 學號,學生名,排名,平均成績(不考慮並列) 對平均成績高到低及學號低到高排序
- 查詢所有學生的平均成績 並排名 , 學號,學生名,排名,平均成績(考慮並列) 對平均成績高到低及學號低到高排序
- 查詢課程有學生的成績是其他人成績兩倍的學號 學生名
解答
1~50題解答
- 查詢學生表的 前10條資料
1
2SELECT * FROM `student`
LIMIT 10; - 查詢成績表所有成績的最低分,平均分,總分
1
SELECT MIN(`score`), AVG(`score`), SUM(`score`) FROM `score`;
- 查詢老師 “諶燕” 所帶的課程設數量
1
2
3
4
5SELECT COUNT(`cno`) FROM `course`
WHERE `tno` = (
SELECT `tno` FROM `teacher`
WHERE `tname` = "諶燕"
); - 查詢所有老師所帶 的課程 數量
1
2
3SELECT `teacher`.`tno`, COUNT(*) FROM `teacher`
JOIN `course` ON `teacher`.`tno` = `course`.`tno`
GROUP BY(`tno`); - 查詢姓”張”的學生名單
1
2SELECT * FROM `student`
WHERE `sname` LIKE "張%"; - 查詢課程名稱為’Oracle’且分數低於60 的學號和分數
1
2
3
4
5SELECT `sno`, `score` FROM `score`
WHERE `score` < 60 AND `cno` = (
SELECT `cno` FROM `course`
WHERE `cname` = "Oracle"
); - 查詢所有學生的選課 課程名稱
1
2SELECT `sno`, `cname` FROM `course`
JOIN `score` ON `course`.`cno` = `score`.`cno`; - 查詢任何一門課程成績在70 分以上的學生姓名.課程名稱和分數
1
2
3
4
5
6-- 1. 將score連結student&course
-- 2. 篩選70分與所選表格
SELECT `sname`, `cname`, `score` FROM `score`
JOIN `student` ON `score`.`sno` = `student`.`sno`
JOIN `course` ON `score`.`cno` = `course`.`cno`
WHERE score > 70; - 查詢不及格的課程,並按課程號從大到小排列 學號,課程號,課程名,分數
1
2
3
4SELECT `sno`, `score`.`cno`, `cname`, `score` FROM `score`
JOIN `course` ON `score`.`cno` = `course`.`cno`
WHERE `score` < 60
ORDER BY `cno` DESC; - 查詢沒學過”諶燕”老師講授的任一門課程的學號,學生姓名
1
2
3
4
5
6
7
8
9
10
11
12
13-- 1. 查 學過”諶燕”的學號
-- 2. 所有 - 學過 = 沒學過
SELECT `sno`, `sname` FROM `student` -- 4. 所有 - 學過 = 沒學過
WHERE `sno` NOT IN(
SELECT `sno` FROM `score` -- 3. 修過"諶燕"教的課
WHERE `cno` IN(
SELECT `cno` FROM `course` -- 2. "諶燕"教的課程編號
WHERE `tno` IN(
SELECT `tno` FROM `teacher` -- 1. "諶燕"教師編號
WHERE `tname` = "諶燕"
)
)
); - 查詢兩門以上不及格課程的同學的學號及其平均成績
1
2
3
4
5
6
7
8-- << HAVING function >>
-- 1. 將兩門以上不及格的學號篩選
-- 2. 輸出學號, 平均成績
-- 3. 使用HAVING COUNT篩選兩門以上
SELECT `sno`, AVG(`score`) FROM `score`
WHERE `score` < 60
GROUP BY `sno`
HAVING COUNT(`score`) >= 2; - 檢索’c004’課程分數小於60,按分數降序排列的同學學號
1
2
3SELECT `sno`, `score` FROM `score`
WHERE `cno` = "c004" AND `score` < 60
ORDER BY `score` DESC; - 查詢’c001’課程比’c002’課程成績高的所有學生的學號
1
2
3-- << 比較相同表格 >>
SELECT a.`sno` FROM `score` `a`, `score` `b`
WHERE a.`sno` = b.`sno` AND a.`cno` = "c001" AND b.`cno` = "c002" AND a.`score` > b.`score`; - 查詢平均成績大於60 分的同學的學號和平均成績
1
2
3SELECT `sno`, AVG(`score`) FROM `score`
GROUP BY `sno`
HAVING AVG(`score`) > 60; - 查詢所有同學的學號.姓名.選課數.總成績
1
2
3
4
5-- 1. 將`score`結合`student`
-- 2. 依`sno`群組區分
SELECT `score`.`sno`, `sname`, COUNT(`cno`) AS "選課數" ,SUM(`score`) AS "總成績" FROM `score`
JOIN `student` ON `score`.`sno` = `student`.`sno`
GROUP BY `score`.`sno`; - 查詢姓”劉”的老師的個數
1
2SELECT COUNT(`tno`) FROM `teacher`
WHERE `tname` LIKE "劉%"; - 查詢只學”諶燕”老師所教的課的同學的學號:姓名
1
2
3
4
5
6
7
8
9
10
11-- 難度: * * *
SELECT DISTINCT `sno`,`sname` FROM `score`
LEFT JOIN `student` USING(sno) -- 3. 連結`score` & `student`
WHERE `sno` NOT IN ( -- 4. 所有學號 - 沒修過"諶燕"的學生
SELECT `sno` FROM `score` -- 2. 篩選沒修過"諶燕"的學生
WHERE `cno` NOT IN(
SELECT `cno` FROM `course` -- 1. 篩選"諶燕"課程編號
LEFT JOIN `teacher` USING(`tno`)
WHERE `tname` = "諶燕"
)
); - 查詢學過”c001″並且也學過編號”c002″課程的同學的學號.姓名
1
2
3
4
5
6
7
8
9SELECT * FROM `student`
WHERE `sno` IN( -- 3. 篩選相同的學號
SELECT `sno` FROM `score` -- 1. 篩選修過c001的學號
WHERE `cno` = "c001"
)
AND `sno` IN(
SELECT `sno` FROM `score` -- 2. 篩選修過c002的學號
WHERE `cno` = "c002"
); - 查詢學過”諶燕”老師所教的所有課的同學的學號:姓名
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19-- 難度 : * * *
-- 自訂表格
SELECT `sno`, `sname` FROM `score` `x`
LEFT JOIN `student` USING(`sno`)
WHERE `cno` IN( -- 2. 篩選有修過"諶燕"
SELECT `cno` FROM `course` -- 1. 查"諶燕"的課程編號
WHERE `tno` IN(
SELECT `tno` FROM `teacher`
WHERE `tname` = "諶燕"
)
)
GROUP BY `sno`
HAVING COUNT(*) =( -- 3. 篩選修課數量與"諶燕"教的課程相同
SELECT COUNT(`cno`) FROM `course`
WHERE `tno` IN(
SELECT `tno` FROM `teacher`
WHERE `tname` = "諶燕"
)
); - 查詢課程編號”c004″的成績比課程編號”c001″和”c002″課程低的所有同學的學號.姓名
1
2
3
4
5
6
7
8
9
10SELECT `sno`, `sname` FROM `student`
WHERE `sno` IN(
SELECT`a`.`sno` FROM `score` `a`, `score` `b`, `score` `c` -- 同表複製為`a`, `b`, `c`
WHERE `a`.`sno` = `b`.`sno`
AND `a`.`cno` = "c004"
AND `b`.`cno` = "c001"
AND `c`.`cno` = "c002"
AND `a`.`score` < `b`.`score`
AND `a`.`score` < `c`.`score`
); - 查詢所有課程成績小於60 分的同學的學號.姓名
1
2
3
4
5
6
7
8SELECT DISTINCT `sno`, `sname` FROM `student`
WHERE `sno` IN(
SELECT `a`.`sno` FROM `score` `a`
WHERE `a`.`score` < 60 AND `a`.`sno` NOT IN( -- `a`均小於60 and 不在 `b`有及格分數
SELECT `b`.`sno` FROM `score` `b`
WHERE `b`.`score` > 60
)
); - 查詢沒有學課的同學的學號.姓名
1
2
3
4SELECT `sno`, `sname` FROM `student`
WHERE `sno` NOT IN( -- 2. 全部學號 - 有修課的學號
SELECT DISTINCT `sno` FROM `score` -- 1. 有修課的學號
); - 查詢與學號為”s001″一起上過課的同學的學號和姓名
1
2
3
4
5
6
7
8
9
10-- 1. 篩選"s001"修過的課
-- 2. 從`score`篩選修過這些課的學號
SELECT `sno`, `sname` FROM `student`
WHERE `sno` IN(
SELECT DISTINCT `sno` FROM `score`
WHERE `cno` IN(
SELECT `cno` FROM `score`
WHERE `sno` = "s001"
)
); - 查詢跟學號為”s005″所修課程完全一樣的同學的學號和姓名
1
2
3
4
5
6
7
8SELECT `sno`, `sname` FROM `score` `x`
LEFT JOIN `student` USING(`sno`)
WHERE `sno` != "s005" -- 2. 排除"s005"
GROUP BY `sno`
HAVING COUNT(*) = ( -- 1. 修課數量與"s005"相同
SELECT COUNT(`cno`) FROM `score`
WHERE `sno` = "s005"
); - 查詢各科成績最高和最低的分 顯示:課程ID,最高分,最低分
1
2SELECT `a`.`cno`, MAX(`a`.`score`), MIN(`b`.`score`) FROM `score` `a`, `score` `b`
GROUP BY `cno`; - 按各科平均成績和及格率的百分數 照平均從低到高顯示
1
2
3
4
5-- COMCAT, SUBSTR function
SELECT `cno`, CONCAT(SUBSTR(AVG(`score`)/100, 1, 4),"%") AS `pass` -- COMCAT(a,b) 連結字串a,b SUBSTR("x",a,b) 擷取"x"a到b
FROM `score`
GROUP BY `cno`
ORDER BY `pass`; - 查詢每個課程的老師及平均分從高到低顯示 老師名稱,課程名稱,平均分數
1
2
3
4
5SELECT `tname`, `cname`, AVG(`score`) FROM `score`
LEFT JOIN `course` USING(`cno`)
LEFT JOIN `teacher` USING(`tno`)
GROUP BY `cno`, `tno` -- 依課程編號, 教師編號分組
ORDER BY AVG(`score`) DESC; - 統計列印各科成績,各分數段人數:課程ID,課程名稱,verygood[100-86], good[85-71], bad[<60]
1
2
3
4
5
6
7
8
9
10-- 難度 : * * * * *
-- CASE WHEN THEN END function
SELECT `cno`, `cname`,
COUNT(CASE WHEN score > 86 THEN 1 END) AS `verygood`, -- 3. 計算符合條件的數量
COUNT(CASE WHEN score BETWEEN 61 AND 85 THEN 1 END) AS `good`,
COUNT(CASE WHEN score < 60 THEN 1 END) AS `bad`
FROM `score`
LEFT JOIN `course` USING(`cno`) -- 1. 連結`score` & `course`
GROUP BY `cno`, `cname` -- 2. 以`cno`, `cname`分組
ORDER BY `cno`; - 查詢各科成績前三名的記錄:(不考慮成績並列情況)
1
2
3
4
5
6
7-- 難度 : * * *
SELECT * FROM `score` `a`
WHERE (
SELECT COUNT(*) FROM `score` `b`
WHERE `a`.`cno` = `b`.`cno` AND `a`.`score` < `b`.`score`
) < 3 -- 取前三筆資料
ORDER BY `cno`, `score` DESC; - 查詢每門課程被選修的學生數
1
2
3
4SELECT `cno`, COALESCE(COUNT(`sno`), 0) FROM `score`
RIGHT JOIN `course` USING(`cno`)
GROUP BY `cno`
ORDER BY `cno`; - 查詢出只選修了兩門課程的全部學生的學號和姓名
1
2
3
4
5
6SELECT `sno`, `sname` FROM `student`
WHERE `sno` IN(
SELECT `sno` FROM `score`
GROUP BY `sno`
HAVING COUNT(`cno`) = 2
); - 查詢男生.女生人數
1
2SELECT `ssex`, COUNT(*) FROM `student`
GROUP BY `ssex`;- 查詢每個課程的男生女生總數
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16-- *****
-- 1. 計算每個課程男生總數
-- 2. 計算每個課程女生總數
-- 3. 合併
SELECT `cno`, COALESCE(boy, 0) AS `boy`, COALESCE(girl, 0) AS `girl` FROM `course`
LEFT JOIN(
SELECT `cno`, COUNT(*) AS `boy` FROM `score` -- 1.
LEFT JOIN `student` USING(`sno`)
WHERE `ssex` = "男"
GROUP BY `cno`) AS `cb` USING(`cno`)
LEFT JOIN(
SELECT `cno`, COUNT(*) AS `girl` FROM `score` -- 2.
LEFT JOIN `student` USING(`sno`)
WHERE `ssex` = "女"
GROUP BY`cno`) AS `cg` USING(`cno`)
GROUP BY `cno`;
- 查詢每個課程的男生女生總數
- 查詢同名同姓學生名單,並統計同名人數
1
2SELECT COUNT(*) AS "同名同姓人數" FROM `student` `a`, `student` `b`
WHERE `a`.`sname` = `b`.`sname` AND `a`.`sno` != `b`.`sno`; - 查詢年紀最小跟最大的學生名單(注:Student 表中Sage 列的型別是int)
1
2
3
4
5
6
7-- 難度 : *
SELECT * FROM `student`
WHERE `sage` = (
SELECT MAX(`sage`) FROM `student` -- 1. 查最大的年紀
) OR `sage` = (
SELECT MIN(`sage`) FROM `student` -- 2. 查最小的年紀
); - 查詢每門課程的平均成績,結果按平均成績升序排列,平均成績相同時,按課程號降序排列
1
2
3SELECT `cno`, AVG(`score`) FROM `score`
GROUP BY `cno`
ORDER BY AVG(`score`) DESC, `cno` DESC; - 查詢平均成績大於85 的所有學生的學號.姓名和平均成績
1
2
3
4SELECT `sno`, `sname`, AVG(`score`) FROM `score`
LEFT JOIN `student` USING(`sno`)
GROUP BY `sno`
HAVING AVG(`score`) >= 85; - 查詢課程編號為c001 且課程成績在80 分以上的學生的學號和姓名
1
2
3
4
5SELECT `sno`, `sname` FROM `student`
WHERE `sno` IN(
SELECT `sno` FROM `score`
WHERE `cno` = "c001" AND `score` >= 80
); - 檢索每課程第二高分的學號 分數(考慮成績並列)
1
-- *****
- 求選了課程的學生人數
1
2
3SELECT COUNT(*) FROM (
SELECT DISTINCT `sno` FROM `score` -- 1. 篩選已修課學號
) AS `score_a`; -- 2. 命名此表為`score_a`, 並計算筆數 - 查詢選修”諶燕”老師所授課程的學生中,成績最高的學生姓名及其成績
1
-- *****
- 查詢不同課程成績有相同的學生的學號.課程號.學生成績
1
2
3
4
5
6-- 難度 : * * * * *
SELECT * FROM `score` `x`, `score` `y`
WHERE `x`.`sno` = `y`.`sno` -- 1. 相同學號對映不同課程
AND `x`.`cno` <> `y`.`cno` -- 2. 排除相同課程比較
AND `x`.`score` = `y`.`score` -- 3. 比較相同分數
; - 所有課程排名成績(不考慮並列) 學號,課程號,排名,成績 照課程,排名排序
1
2
3
4SELECT * FROM `score` `x`, `score` `y`
WHERE `x`.`sno` = `y`.`sno` -- 1. 相同學號對映不同課程
AND `x`.`cno` <> `y`.`cno` -- 2. 排除相同課程比較
AND `x`.`score` = `y`.`score`; -- 3. 比較相同分數 - 所有課程排名成績(考慮並列) 學號,課程號,排名,成績 照課程,排名排序
1
-- *****
- 做所有學生顯示學生名稱,課程名稱,成績,老師名稱的視圖
1
-- *****
- 查詢上過所有老師教的課程的學生 學號,學生名
1
2
3
4
5
6
7
8-- 難度 : * * * * *
-- GROUP_CONCAT
SELECT sno,sname FROM `score`
LEFT JOIN course USING(cno)
LEFT JOIN student USING(sno)
GROUP BY sno
HAVING GROUP_CONCAT(DISTINCT tno ORDER BY tno) = (
SELECT GROUP_CONCAT(tno ORDER BY tno) FROM teacher); - 查詢包含數字的課程名
1
2
3
4-- 難度 : *
-- REGEXP function
SELECT * FROM `course`
WHERE `cname` REGEXP "[0-9]"; - 查詢只有英文的課程名
1
2
3-- 難度 : *
SELECT * FROM `course`
WHERE `cname` REGEXP "^([a-z]|[A-Z])+$"; - 查詢所有學生的平均成績 並排名 , 學號,學生名,排名,平均成績(不考慮並列) 對平均成績高到低及學號低到高排序
1
-- *****
- 查詢所有學生的平均成績 並排名 , 學號,學生名,排名,平均成績(考慮並列) 對平均成績高到低及學號低到高排序
1
-- *****
- 查詢課程有學生的成績是其他人成績兩倍的學號 學生名
1