sql语句练习(一)
以下為數據庫sql50中的四張表,其結構如下:
學生表t_student——學生編號(stu_id),學生姓名(stu_name),出生年月(stu_birth),學生性別(stu_sex)
教師表t_teacher——教師編號(tea_id),教師姓名(tea_name)
課程表t_course——課程編號(cou_id),課程名稱(cou_name),教師編號(tea_id)
成績表t_score——學生編號(stu_id),課程編號(cou_id),學生成績(stu_score)
1. 查詢“01”課程比“02”課程成績高的學生的信息及其課程分數。
知識點:自聯結、顯式內部聯結(INNER JOIN)
方法一:分兩步查詢(自聯結>內部聯結) mysql> SELECT c.*, score_01 AS '01', score_02 AS '02'-> FROM t_student c-> INNER JOIN (-> SELECT a.stu_id, a.cou_id cou_01, a.stu_score score_01, b.cou_id cou_02, b.stu_score score_02-> FROM t_score a-> INNER JOIN t_score b ON a.stu_id = b.stu_id AND b.cou_id = '02' AND a.stu_score > b.stu_score-> WHERE a.cou_id = '01')t-> ON c.stu_id = t.stu_id; +--------+----------+------------+---------+------+------+ | stu_id | stu_name | stu_birth | stu_sex | 01 | 02 | +--------+----------+------------+---------+------+------+ | 02 | 錢電 | 1990-12-21 | 男 | 70 | 60 | | 04 | 李云 | 1990-08-06 | 男 | 50 | 30 | +--------+----------+------------+---------+------+------+方法二:內部聯結、自聯結 mysql> SELECT a.*, b.stu_score AS '01', c.stu_score AS '02'-> FROM t_student a-> INNER JOIN t_score b ON a.stu_id = b.stu_id AND b.cou_id = '01'-> INNER JOIN t_score c ON a.stu_id = c.stu_id AND c.cou_id = '02'-> WHERE b.stu_score > c.stu_score;2. 查詢“01”課程比“02”課程成績低的學生的信息及其課程分數。
知識點:隱式內部聯結
mysql> SELECT a.*, b.stu_score AS '01', c.stu_score AS '02'-> FROM t_student a, t_score b, t_score c-> WHERE a.stu_id = b.stu_id AND a.stu_id = c.stu_id-> AND b.cou_id = '01' AND c.cou_id = '02'-> AND b.stu_score < c.stu_score; +--------+----------+------------+---------+------+------+ | stu_id | stu_name | stu_birth | stu_sex | 01 | 02 | +--------+----------+------------+---------+------+------+ | 01 | 趙雷 | 1990-01-01 | 男 | 80 | 90 | | 05 | 周梅 | 1991-12-01 | 女 | 76 | 87 | +--------+----------+------------+---------+------+------+3. 查詢平均成績及格(大于、等于60分)的學生的編號、姓名及平均成績。
知識點:AVG()函數、ROUND(x,d)函數、GROUP BY分組、HAVING過濾(分組后)、內部聯結
方法一:分兩步查詢(過濾>內部聯結) mysql> SELECT a.stu_id, stu_name, score_avg-> FROM t_student a-> INNER JOIN (-> SELECT stu_id, ROUND(AVG(stu_score), 2) score_avg-> FROM t_score-> GROUP BY stu_id-> HAVING score_avg >= 60)t-> ON a.stu_id = t.stu_id; +--------+----------+-----------+ | stu_id | stu_name | score_avg | +--------+----------+-----------+ | 01 | 趙雷 | 89.67 | | 02 | 錢電 | 70.00 | | 03 | 孫風 | 80.00 | | 05 | 周梅 | 81.50 | | 07 | 鄭竹 | 93.50 | +--------+----------+-----------+方法二:內部聯結 mysql> SELECT a.stu_id, stu_name, ROUND(AVG(stu_score), 2) score_avg-> FROM t_student a-> INNER JOIN t_score b ON a.stu_id = b.stu_id-> GROUP BY b.stu_id-> HAVING score_avg >= 60;4. 查詢平均成績不及格(小于60分)的學生的編號、姓名、平均成績。(包括沒有成績的同學)
知識點:NOT EXISTS關鍵字、UNION操作符、內部聯結
步驟1:檢索平均成績不合格的學生信息 mysql> SELECT a.stu_id, stu_name, ROUND(AVG(stu_score), 2) score_avg-> FROM t_student a-> INNER JOIN t_score b ON a.stu_id = b.stu_id-> GROUP BY b.stu_id-> HAVING score_avg < 60; +--------+----------+-----------+ | stu_id | stu_name | score_avg | +--------+----------+-----------+ | 04 | 李云 | 33.33 | | 06 | 吳蘭 | 32.50 | +--------+----------+-----------+步驟2:檢索沒有成績的學生(NOT EXISTS) mysql> SELECT a.stu_id, stu_name, 0 AS score_avg-> FROM t_student a-> WHERE NOT EXISTS (-> SELECT * FROM t_score b-> WHERE a.stu_id = b.stu_id); +--------+----------+-----------+ | stu_id | stu_name | score_avg | +--------+----------+-----------+ | 08 | 王菊 | 0 | +--------+----------+-----------+ 步驟2:檢索沒有成績的學生(NOT IN) mysql> SELECT a.stu_id, stu_name, 0 AS score_avg-> FROM t_student a-> WHERE a.stu_id NOT IN (-> SELECT stu_id FROM t_score); +--------+----------+-----------+ | stu_id | stu_name | score_avg | +--------+----------+-----------+ | 08 | 王菊 | 0 | +--------+----------+-----------+步驟3:UNION操作符連接兩個表(步驟1+步驟2) mysql> SELECT a.stu_id, stu_name, ROUND(AVG(stu_score), 2) score_avg-> FROM t_student a-> INNER JOIN t_score b ON a.stu_id = b.stu_id-> GROUP BY b.stu_id-> HAVING score_avg < 60-> UNION-> SELECT a.stu_id, stu_name, 0 AS score_avg-> FROM t_student a-> WHERE NOT EXISTS (-> SELECT * FROM t_score b-> WHERE a.stu_id = b.stu_id); +--------+----------+-----------+ | stu_id | stu_name | score_avg | +--------+----------+-----------+ | 04 | 李云 | 33.33 | | 06 | 吳蘭 | 32.50 | | 08 | 王菊 | 0.00 | +--------+----------+-----------+5. 查詢所有學生的編號、姓名、選課數、課程總成績。
知識點:外部聯結(LEFT OUTER JOIN)
**注意:**因為是左外部聯結,所以在GROUP BY子句中,應以表a的stu_id為準,否則會報錯。
6. 查詢“李”姓老師的數量。
知識點:LIKE操作符(用通配符%進行過濾)
mysql> SELECT COUNT(tea_name)-> FROM t_teacher-> WHERE tea_name LIKE '李%'; +-----------------+ | COUNT(tea_name) | +-----------------+ | 1 | +-----------------+7. 查詢考了“張三”老師課程的學生的信息。
知識點:子查詢、內部聯結(INNER JOIN)
方法一:子查詢、內部聯結 mysql> SELECT c.*-> FROM t_student c-> INNER JOIN t_score d ON c.stu_id = d.stu_id-> AND d.cou_id IN (-> SELECT cou_id-> FROM t_course a-> INNER JOIN t_teacher b ON a.tea_id = b.tea_id AND tea_name = '張三'); +--------+----------+------------+---------+ | stu_id | stu_name | stu_birth | stu_sex | +--------+----------+------------+---------+ | 01 | 趙雷 | 1990-01-01 | 男 | | 02 | 錢電 | 1990-12-21 | 男 | | 03 | 孫風 | 1990-05-20 | 男 | | 04 | 李云 | 1990-08-06 | 男 | | 05 | 周梅 | 1991-12-01 | 女 | | 07 | 鄭竹 | 1989-07-01 | 女 | +--------+----------+------------+---------+方法二:內部聯結 mysql> SELECT a.*-> FROM t_student a-> INNER JOIN t_score b ON a.stu_id = b.stu_id-> INNER JOIN t_course c ON b.cou_id = c.cou_id-> INNER JOIN t_teacher d ON c.tea_id = d.tea_id AND tea_name = '張三';8. 查詢沒有考“張三”老師課程的學生的信息。
知識點:子查詢、內部聯結(INNER JOIN)、NOT IN 操作符
**注意:**不能使用第7題的方法二(tea_name != '張三'),因為一個學生可以選擇多門課程,具體見測試數據。所以應該先設定條件(stu_id),再進行內部聯結。
9. 查詢考了“01”課程和“02”課程的學生的信息。
知識點:自聯結、內部聯結
mysql> SELECT a.*-> FROM t_student a-> INNER JOIN t_score b ON a.stu_id = b.stu_id AND b.cou_id = '01'-> INNER JOIN t_score c ON a.stu_id = c.stu_id AND c.cou_id = '02'; +--------+----------+------------+---------+ | stu_id | stu_name | stu_birth | stu_sex | +--------+----------+------------+---------+ | 01 | 趙雷 | 1990-01-01 | 男 | | 02 | 錢電 | 1990-12-21 | 男 | | 03 | 孫風 | 1990-05-20 | 男 | | 04 | 李云 | 1990-08-06 | 男 | | 05 | 周梅 | 1991-12-01 | 女 | +--------+----------+------------+---------+10. 查詢考了“01”課程但沒考“02”課程的學生的信息。
知識點:子查詢
mysql> SELECT a.*-> FROM t_student a-> WHERE a.stu_id IN (-> SELECT stu_id FROM t_score WHERE cou_id = '01')-> AND a.stu_id NOT IN (-> SELECT stu_id FROM t_score WHERE cou_id = '02'); +--------+----------+------------+---------+ | stu_id | stu_name | stu_birth | stu_sex | +--------+----------+------------+---------+ | 06 | 吳蘭 | 1992-03-01 | 女 | +--------+----------+------------+---------+11. 查詢沒有考全所有課程的學生的信息。(不包括沒參加考試的學生)
知識點:內部聯結、IN 操作符、子查詢
步驟1:檢索考試科目數小于課程總數的學生 mysql> SELECT *-> FROM (-> SELECT stu_id, COUNT(cou_id) stu_cou_number-> FROM t_score-> GROUP BY stu_id)t-> WHERE stu_cou_number < (-> SELECT COUNT(*) cou_number FROM t_course); +--------+----------------+ | stu_id | stu_cou_number | +--------+----------------+ | 05 | 2 | | 06 | 2 | | 07 | 2 | +--------+----------------+步驟2::檢索學生具體信息(依據步驟1) mysql> SELECT *-> FROM t_student a-> WHERE a.stu_id IN (-> SELECT stu_id FROM (-> SELECT stu_id, COUNT(cou_id) stu_cou_number FROM t_score GROUP BY stu_id)t-> WHERE stu_cou_number < (SELECT COUNT(*) cou_number FROM t_course)); +--------+----------+------------+---------+ | stu_id | stu_name | stu_birth | stu_sex | +--------+----------+------------+---------+ | 05 | 周梅 | 1991-12-01 | 女 | | 06 | 吳蘭 | 1992-03-01 | 女 | | 07 | 鄭竹 | 1989-07-01 | 女 | +--------+----------+------------+---------+12. 查詢沒有考全所有課程的學生的信息。(包括沒參加考試的學生)
知識點:自聯結、內部聯結、NOT IN 操作符
步驟1:檢索學全了三門課程的學生stu_id mysql> SELECT a.stu_id-> FROM t_score a-> INNER JOIN t_score b ON a.stu_id = b.stu_id AND b.cou_id = '02'-> INNER JOIN t_score c ON a.stu_id = c.stu_id AND c.cou_id = '03'-> WHERE a.cou_id = '01'; +--------+ | stu_id | +--------+ | 01 | | 02 | | 03 | | 04 | +--------+步驟2:依據:步驟1的stu_id排除學生 mysql> SELECT d.*-> FROM t_student d-> WHERE d.stu_id NOT IN (-> SELECT a.stu_id-> FROM t_score a-> INNER JOIN t_score b ON a.stu_id = b.stu_id AND b.cou_id = '02'-> INNER JOIN t_score c ON a.stu_id = c.stu_id AND c.cou_id = '03'-> WHERE a.cou_id = '01') ; +--------+----------+------------+---------+ | stu_id | stu_name | stu_birth | stu_sex | +--------+----------+------------+---------+ | 05 | 周梅 | 1991-12-01 | 女 | | 06 | 吳蘭 | 1992-03-01 | 女 | | 07 | 鄭竹 | 1989-07-01 | 女 | | 08 | 王菊 | 1990-01-20 | 女 | +--------+----------+------------+---------+13. 查詢至少有一門課與“01”號學生所考課程相同的學生的信息。
知識點:內部聯結、子查詢、IN 操作符、DISTINCT關鍵字
**注意:**方法一中需要使用DISTINCT關鍵字,因為是內聯結,行數是成績表的行數,導致數據冗余。
14. 查詢沒考“張三”老師講授的任一門課程的學生姓名。
知識點:子查詢、NOT IN 操作符
**注意:**不能將學生表和成績表內聯結,以cou_id作為條件(NOT IN),因為一個學生可以選擇多門課程(同第8題)。還是用排除法吧,先檢索選了“張三”老師課程的stu_id,再排除。
15. 查詢兩門及其以上不及格課程的學生的學號、姓名及其平均成績。
知識點:COUNT()函數、ROUND(x,d)函數、AVG()函數、子查詢、GROUP BY分組、HAVING分組后過濾、子查詢、內部聯結
mysql> SELECT a.stu_id, stu_name, score_avg-> FROM t_student a, (-> SELECT stu_id, COUNT(cou_id) stu_cou, ROUND(AVG(stu_score),2) score_avg-> FROM t_score-> WHERE stu_score < 60-> GROUP BY stu_id-> HAVING stu_cou >= 2)t-> WHERE a.stu_id = t.stu_id; +--------+----------+-----------+ | stu_id | stu_name | score_avg | +--------+----------+-----------+ | 04 | 李云 | 33.33 | | 06 | 吳蘭 | 32.50 | +--------+----------+-----------+16. 檢索“01”課程分數小于60分,按分數降序排列的學生信息。
知識點:內部聯結、ORDER BY子句、DESC關鍵字
mysql> SELECT a.*, stu_score-> FROM t_student a-> INNER JOIN (-> SELECT *-> FROM t_score-> WHERE cou_id = '01' AND stu_score < 60)b-> ON a.stu_id = b.stu_id-> ORDER BY stu_score DESC; +--------+----------+------------+---------+-----------+ | stu_id | stu_name | stu_birth | stu_sex | stu_score | +--------+----------+------------+---------+-----------+ | 04 | 李云 | 1990-08-06 | 男 | 50 | | 06 | 吳蘭 | 1992-03-01 | 女 | 31 | +--------+----------+------------+---------+-----------+17. 按各科成績進行排序,并顯示排名。
知識點:窗口函數中的序號函數(RANK())、DESC關鍵字、內部聯結
mysql> SELECT a.stu_id, stu_name, cou_name, stu_score,-> RANK() OVER (PARTITION BY b.cou_id ORDER BY stu_score DESC) 'cou_range'-> FROM t_student a-> INNER JOIN t_score b ON a.stu_id = b.stu_id-> INNER JOIN t_course c ON b.cou_id = c.cou_id; +--------+----------+----------+-----------+-----------+ | stu_id | stu_name | cou_name | stu_score | cou_range | +--------+----------+----------+-----------+-----------+ | 01 | 趙雷 | 語文 | 80 | 1 | | 03 | 孫風 | 語文 | 80 | 1 | | 05 | 周梅 | 語文 | 76 | 3 | | 02 | 錢電 | 語文 | 70 | 4 | | 04 | 李云 | 語文 | 50 | 5 | | 06 | 吳蘭 | 語文 | 31 | 6 | | 01 | 趙雷 | 數學 | 90 | 1 | | 07 | 鄭竹 | 數學 | 89 | 2 | | 05 | 周梅 | 數學 | 87 | 3 | | 03 | 孫風 | 數學 | 80 | 4 | | 02 | 錢電 | 數學 | 60 | 5 | | 04 | 李云 | 數學 | 30 | 6 | | 01 | 趙雷 | 英語 | 99 | 1 | | 07 | 鄭竹 | 英語 | 98 | 2 | | 02 | 錢電 | 英語 | 80 | 3 | | 03 | 孫風 | 英語 | 80 | 3 | | 06 | 吳蘭 | 英語 | 34 | 5 | | 04 | 李云 | 英語 | 20 | 6 | +--------+----------+----------+-----------+-----------+18. 查詢學生的總成績并進行排名。
知識點:窗口函數中的序號函數(RANK())、SUM()函數、內部聯結
mysql> SELECT a.stu_id '編號', stu_name '姓名', SUM(stu_score) '總成績',-> RANK() OVER (ORDER BY SUM(stu_score) DESC) '排名'-> FROM t_student a-> INNER JOIN t_score b ON a.stu_id = b.stu_id-> GROUP BY b.stu_id; +--------+--------+-----------+--------+ | 編號 | 姓名 | 總成績 | 排名 | +--------+--------+-----------+--------+ | 01 | 趙雷 | 269 | 1 | | 03 | 孫風 | 240 | 2 | | 02 | 錢電 | 210 | 3 | | 07 | 鄭竹 | 187 | 4 | | 05 | 周梅 | 163 | 5 | | 04 | 李云 | 100 | 6 | | 06 | 吳蘭 | 65 | 7 | +--------+--------+-----------+--------+19. 查詢不同老師所教的不同課程的平均分,并從高到低顯示 。
知識點:ROUND()函數、AVG()函數、窗口函數中的序號函數(ROW_NUMBER())、內部聯結(隱式)
注意:ORDER BY子句中,不要用'課程平均分'。
20. 查詢所有課程的成績第2、3名的學生信息及該課程成績。
知識點:窗口函數中的序號函數(ROW_NUMBER())、內部聯結、子查詢、IN操作符
mysql> SELECT *-> FROM (-> SELECT a.stu_id, stu_name, cou_name, stu_score,-> ROW_NUMBER() OVER (PARTITION BY c.cou_id ORDER BY stu_score DESC) score_order-> FROM t_student a-> INNER JOIN t_score b ON a.stu_id = b.stu_id-> INNER JOIN t_course c ON b.cou_id = c.cou_id)t-> WHERE t.score_order IN (2,3); +--------+----------+----------+-----------+-------------+ | stu_id | stu_name | cou_name | stu_score | score_order | +--------+----------+----------+-----------+-------------+ | 03 | 孫風 | 語文 | 80 | 2 | | 05 | 周梅 | 語文 | 76 | 3 | | 07 | 鄭竹 | 數學 | 89 | 2 | | 05 | 周梅 | 數學 | 87 | 3 | | 07 | 鄭竹 | 英語 | 98 | 2 | | 02 | 錢電 | 英語 | 80 | 3 | +--------+----------+----------+-----------+-------------+21. 統計各科成績:課程編號、課程名稱、及格人數、及格率。
知識點:SUM()函數、ROUND(x,d)函數、CASE WHEN 條件 THEN... ELSE... END、內部聯結
mysql> SELECT a.cou_id '課程編號', cou_name '課程名稱',-> SUM(CASE WHEN stu_score >= 60 THEN 1 ELSE 0 END) '及格人數',-> ROUND(100 * SUM(CASE WHEN stu_score >= 60 THEN 1 ELSE 0 END) / COUNT(*) , 2) '及格率'-> FROM t_course a-> INNER JOIN t_score b ON a.cou_id = b.cou_id-> GROUP BY b.cou_id; +--------------+--------------+--------------+-----------+ | 課程編號 | 課程名稱 | 及格人數 | 及格率 | +--------------+--------------+--------------+-----------+ | 01 | 語文 | 4 | 66.67 | | 02 | 數學 | 5 | 83.33 | | 03 | 英語 | 4 | 66.67 | +--------------+--------------+--------------+-----------+22. 查詢學生的平均成績及名次。
知識點:AVG()函數、ROUND(x,d)函數、窗口函數中的序號函數(ROW_NUMBER())、內部聯結
mysql> SELECT a.stu_id '學生編號', stu_name '學生姓名',-> ROUND(AVG(stu_score), 2) '平均成績',-> ROW_NUMBER() OVER (ORDER BY ROUND(AVG(stu_score), 2) DESC) '排名'-> FROM t_student a-> INNER JOIN t_score b ON a.stu_id = b.stu_id-> GROUP BY b.stu_id; +--------------+--------------+--------------+--------+ | 學生編號 | 學生姓名 | 平均成績 | 排名 | +--------------+--------------+--------------+--------+ | 07 | 鄭竹 | 93.50 | 1 | | 01 | 趙雷 | 89.67 | 2 | | 05 | 周梅 | 81.50 | 3 | | 03 | 孫風 | 80.00 | 4 | | 02 | 錢電 | 70.00 | 5 | | 04 | 李云 | 33.33 | 6 | | 06 | 吳蘭 | 32.50 | 7 | +--------------+--------------+--------------+--------+23. 查詢各科成績前三名的記錄。
知識點:窗口函數中的序號函數(RANK())、內部聯結、子查詢
mysql> SELECT *-> FROM (-> SELECT a.stu_id, stu_name, cou_name, stu_score,-> RANK() OVER(PARTITION BY b.cou_id ORDER BY stu_score DESC) cou_order-> FROM t_student a-> INNER JOIN t_score b ON a.stu_id = b.stu_id-> INNER JOIN t_course c ON b.cou_id = c.cou_id)t-> WHERE cou_order <= 3; +--------+----------+----------+-----------+-----------+ | stu_id | stu_name | cou_name | stu_score | cou_order | +--------+----------+----------+-----------+-----------+ | 01 | 趙雷 | 語文 | 80 | 1 | | 03 | 孫風 | 語文 | 80 | 1 | | 05 | 周梅 | 語文 | 76 | 3 | | 01 | 趙雷 | 數學 | 90 | 1 | | 07 | 鄭竹 | 數學 | 89 | 2 | | 05 | 周梅 | 數學 | 87 | 3 | | 01 | 趙雷 | 英語 | 99 | 1 | | 07 | 鄭竹 | 英語 | 98 | 2 | | 02 | 錢電 | 英語 | 80 | 3 | | 03 | 孫風 | 英語 | 80 | 3 | +--------+----------+----------+-----------+-----------+24. 查詢每門課程的選課數量(按考試人數計算)。
知識點:COUNT()函數、GROUP BY分組
mysql> SELECT cou_id, COUNT(*) cou_num-> FROM t_score-> GROUP BY cou_id; +--------+---------+ | cou_id | cou_num | +--------+---------+ | 01 | 6 | | 02 | 6 | | 03 | 6 | +--------+---------+25. 查詢只考了兩門課程的學生的學號和姓名。
知識點:COUNT()函數、GROUP BY分組、HAVING分組后過濾、內部聯結
**注意:**內部聯結時,不能用COUNT(b.*),否則會報錯
26. 查詢男生、女生人數。
知識點:COUNT()函數、GROUP BY分組
mysql> SELECT stu_sex, COUNT(*) '人數'-> FROM t_student-> GROUP BY stu_sex; +---------+--------+ | stu_sex | 人數 | +---------+--------+ | 男 | 4 | | 女 | 4 | +---------+--------+27. 查詢名字中含有“風”字的學生信息。
知識點:LIKE操作符(用通配符%進行過濾)
mysql> SELECT *-> FROM t_student a-> WHERE a.stu_name LIKE '%風%'; +--------+----------+------------+---------+ | stu_id | stu_name | stu_birth | stu_sex | +--------+----------+------------+---------+ | 03 | 孫風 | 1990-05-20 | 男 | +--------+----------+------------+---------+28. 查詢同名同性的學生名單,并統計同名人數。
知識點:COUNT()函數、GROUP BY分組、HAVING分組后過濾、內部聯結
#新插入3條記錄 mysql> INSERT t_student VALUES-> ('09', '錢電', '1991-12-12', '女'),-> ('10', '錢電', '1991-02-12', '男'),-> ('11', '鄭竹', '1989-08-20', '男');mysql> SELECT a.*, b.name_num-> FROM t_student a-> INNER JOIN (-> SELECT stu_name, COUNT(*) 'name_num'-> FROM t_student-> GROUP BY stu_name-> HAVING name_num > 1)b-> ON a.stu_name = b.stu_name; +--------+----------+------------+---------+----------+ | stu_id | stu_name | stu_birth | stu_sex | name_num | +--------+----------+------------+---------+----------+ | 02 | 錢電 | 1990-12-21 | 男 | 3 | | 07 | 鄭竹 | 1989-07-01 | 女 | 2 | | 09 | 錢電 | 1991-12-12 | 女 | 3 | | 10 | 錢電 | 1991-02-12 | 男 | 3 | | 11 | 鄭竹 | 1989-08-20 | 男 | 2 | +--------+----------+------------+---------+----------+29. 查詢1990年出生的學生名單。
知識點:時間處理函數:Year()
mysql> SELECT *-> FROM t_student-> WHERE Year(stu_birth) = 1990; +--------+----------+------------+---------+ | stu_id | stu_name | stu_birth | stu_sex | +--------+----------+------------+---------+ | 01 | 趙雷 | 1990-01-01 | 男 | | 02 | 錢電 | 1990-12-21 | 男 | | 03 | 孫風 | 1990-05-20 | 男 | | 04 | 李云 | 1990-08-06 | 男 | | 08 | 王菊 | 1990-01-20 | 女 | +--------+----------+------------+---------+30. 查詢每門課程的平均成績,按平均成績降序排列,平均成績相同時,按課程編號升序排列。
知識點:GROUP BY分組、ORDER BY排序(DESC)、內部聯結
mysql> SELECT a.cou_id, cou_name,-> ROUND(AVG(stu_score) ,2) avg_score-> FROM t_course a-> INNER JOIN t_score b ON a.cou_id = b.cou_id-> GROUP BY b.cou_id-> ORDER BY avg_score DESC, cou_id; +--------+----------+-----------+ | cou_id | cou_name | avg_score | +--------+----------+-----------+ | 02 | 數學 | 72.67 | | 03 | 英語 | 68.50 | | 01 | 語文 | 64.50 | +--------+----------+-----------+31. 查詢平均成績大于等于85分的所有學生的學號、姓名和平均成績。
知識點:ROUND()函數、AVG()函數、GROUP BY分組、HAVING分組后過濾、內部聯結
mysql> SELECT a.stu_id, stu_name,-> ROUND(AVG(stu_score),2) avg_score-> FROM t_student a-> INNER JOIN t_score b ON a.stu_id = b.stu_id-> GROUP BY b.stu_id-> HAVING avg_score >= 85; +--------+----------+-----------+ | stu_id | stu_name | avg_score | +--------+----------+-----------+ | 01 | 趙雷 | 89.67 | | 07 | 鄭竹 | 93.50 | +--------+----------+-----------+32. 查詢“數學"成績低于60分的學生姓名和分數。
知識點:內部聯結
mysql> SELECT stu_name, stu_score-> FROM t_student a-> INNER JOIN t_score b ON a.stu_id = b.stu_id AND stu_score < 60-> INNER JOIN t_course c ON b.cou_id = c.cou_id AND cou_name = '數學'; +----------+-----------+ | stu_name | stu_score | +----------+-----------+ | 李云 | 30 | +----------+-----------+33. 查詢任何一門課程成績在70分以上的姓名、課程名稱和分數。
知識點:內部聯結
mysql> SELECT stu_name, cou_name, stu_score-> FROM t_student a-> INNER JOIN t_score b ON a.stu_id = b.stu_id-> INNER JOIN t_course c ON b.cou_id = c.cou_id-> WHERE stu_score > 70; +----------+----------+-----------+ | stu_name | cou_name | stu_score | +----------+----------+-----------+ | 趙雷 | 語文 | 80 | | 趙雷 | 數學 | 90 | | 趙雷 | 英語 | 99 | | 錢電 | 英語 | 80 | | 孫風 | 語文 | 80 | | 孫風 | 數學 | 80 | | 孫風 | 英語 | 80 | | 周梅 | 語文 | 76 | | 周梅 | 數學 | 87 | | 鄭竹 | 數學 | 89 | | 鄭竹 | 英語 | 98 | +----------+----------+-----------+34. 查詢不及格的課程。
知識點:內部聯結
mysql> SELECT stu_name, cou_name, stu_score-> FROM t_student a-> INNER JOIN t_score b ON a.stu_id = b.stu_id-> INNER JOIN t_course c ON b.cou_id = c.cou_id-> WHERE stu_score < 60; +----------+----------+-----------+ | stu_name | cou_name | stu_score | +----------+----------+-----------+ | 李云 | 語文 | 50 | | 李云 | 數學 | 30 | | 李云 | 英語 | 20 | | 吳蘭 | 語文 | 31 | | 吳蘭 | 英語 | 34 | +----------+----------+-----------+35. 查詢課程編號為01且課程成績在70分以上的學生的學號和姓名。
知識點:內部聯結
mysql> SELECT a.stu_id, stu_name-> FROM t_student a-> INNER JOIN t_score b ON a.stu_id = b.stu_id-> WHERE cou_id = 01 AND stu_score > 70; +--------+----------+ | stu_id | stu_name | +--------+----------+ | 01 | 趙雷 | | 03 | 孫風 | | 05 | 周梅 | +--------+----------+36. 查詢“張三”老師所教的課程的成績最高的學生信息及其成績。
知識點:內部聯結、ORDER BY 排序、LIMIT
mysql> SELECT a.*, stu_score-> FROM t_student a-> INNER JOIN t_score b ON a.stu_id = b.stu_id-> INNER JOIN t_course c ON b.cou_id = c.cou_id-> INNER JOIN t_teacher d ON c.tea_id = d.tea_id-> WHERE tea_name = '張三'-> ORDER BY stu_score DESC-> LIMIT 1; +--------+----------+------------+---------+-----------+ | stu_id | stu_name | stu_birth | stu_sex | stu_score | +--------+----------+------------+---------+-----------+ | 01 | 趙雷 | 1990-01-01 | 男 | 90 | +--------+----------+------------+---------+-----------+37. 查詢課程不同成績相同的學生的學生編號、課程編號、學生成績。
知識點:自聯結、DISTINCT關鍵字
mysql> SELECT DISTINCT a.*-> FROM t_score a, t_score b-> WHERE a.stu_score = b.stu_score AND a.cou_id != b.cou_id; +--------+--------+-----------+ | stu_id | cou_id | stu_score | +--------+--------+-----------+ | 02 | 03 | 80 | | 03 | 02 | 80 | | 03 | 03 | 80 | | 01 | 01 | 80 | | 03 | 01 | 80 | +--------+--------+-----------+38 查詢每門課程成績最好的前兩名同學。
知識點:窗口函數中的序號函數(ROW_NUMBER())、內部聯結、子查詢
mysql> SELECT *-> FROM (-> SELECT a.stu_id, stu_name, cou_name, stu_score,-> ROW_NUMBER() OVER (PARTITION BY b.cou_id ORDER BY stu_score DESC) score_order-> FROM t_student a-> INNER JOIN t_score b ON a.stu_id = b.stu_id-> INNER JOIN t_course c ON b.cou_id = c.cou_id)t-> WHERE score_order <= 2; +--------+----------+----------+-----------+-------------+ | stu_id | stu_name | cou_name | stu_score | score_order | +--------+----------+----------+-----------+-------------+ | 01 | 趙雷 | 語文 | 80 | 1 | | 03 | 孫風 | 語文 | 80 | 2 | | 01 | 趙雷 | 數學 | 90 | 1 | | 07 | 鄭竹 | 數學 | 89 | 2 | | 01 | 趙雷 | 英語 | 99 | 1 | | 07 | 鄭竹 | 英語 | 98 | 2 | +--------+----------+----------+-----------+-------------+39. 統計每門課程的選修人數(超過5人的課程才統計)。要求輸出課程號和選修人數,查詢結果按人數降序排列,若人數相同,按課程號升序排列。
知識點:COUNT()函數、GROUP BY分組、HAVING分組后過濾、ORDER BY 排序
mysql> SELECT cou_id, COUNT(*) stu_num-> FROM t_score-> GROUP BY cou_id-> HAVING stu_num > 5-> ORDER BY stu_num DESC, cou_id; +--------+---------+ | cou_id | stu_num | +--------+---------+ | 01 | 6 | | 02 | 6 | | 03 | 6 | +--------+---------+40. 檢索至少選修(參加考試)了兩門課程的學生。
知識點:COUNT()函數、GROUP BY分組、HAVING分組后過濾、內部聯結
mysql> SELECT a.stu_id, stu_name, COUNT(cou_id) stu_cou-> FROM t_student a-> INNER JOIN t_score b ON a.stu_id = b.stu_id-> GROUP BY b.stu_id-> HAVING stu_cou >= 2; +--------+----------+---------+ | stu_id | stu_name | stu_cou | +--------+----------+---------+ | 01 | 趙雷 | 3 | | 02 | 錢電 | 3 | | 03 | 孫風 | 3 | | 04 | 李云 | 3 | | 05 | 周梅 | 2 | | 06 | 吳蘭 | 2 | | 07 | 鄭竹 | 2 | +--------+----------+---------+41. 查詢選修(參加考試)了全部課程的學生信息。
知識點:COUNT()函數、GROUP BY分組、HAVING分組后過濾、內部聯結
mysql> SELECT a.*-> FROM t_student a-> INNER JOIN (-> SELECT stu_id, COUNT(*) stu_cou-> FROM t_score-> GROUP BY stu_id-> HAVING stu_cou = (SELECT COUNT(*) FROM t_course))t-> ON a.stu_id = t.stu_id; +--------+----------+------------+---------+ | stu_id | stu_name | stu_birth | stu_sex | +--------+----------+------------+---------+ | 01 | 趙雷 | 1990-01-01 | 男 | | 02 | 錢電 | 1990-12-21 | 男 | | 03 | 孫風 | 1990-05-20 | 男 | | 04 | 李云 | 1990-08-06 | 男 | +--------+----------+------------+---------+42. 查詢每位學生的年齡。
知識點:
日期和時間處理函數:①Date_Format(data,format),其中%Y(年)、%m(月份)、%d(日);②CurDate()函數:返回當前日期;③Year():返回日期的年份
思路:當前年份-出生年份(當前月份小于出生月份再減1)
43. 查詢本周過生日的學生。
知識點:日期和時間處理函數Week(),返回日期的星期數
#測試函數 mysql> SELECT CurDate() cur_date, Week(CurDate()) cur_week; +------------+----------+ | cur_date | cur_week | +------------+----------+ | 2019-03-10 | 10 | +------------+----------+#完整代碼 mysql> SELECT stu_id, stu_name, stu_birth-> FROM t_student-> WHERE Week(stu_birth) = Week(CurDate()); +--------+----------+-----------+ | stu_id | stu_name | stu_birth | +--------+----------+-----------+ | 09 | 測試 | 1998-3-8 | +--------+----------+-----------+44. 查詢下周過生日的學生。
知識點:日期和時間處理函數Week(),返回日期的星期數
mysql> SELECT stu_id, stu_name, stu_birth-> FROM t_student-> WHERE Week(stu_birth) = Week(CurDate()) + 1;45. 查詢本月過生日的學生。
知識點:日期和時間處理函數Month(),返回日期的月份
mysql> SELECT stu_id, stu_name, stu_birth-> FROM t_student-> WHERE Month(stu_birth) = Month(CurDate()); +--------+----------+------------+ | stu_id | stu_name | stu_birth | +--------+----------+------------+ | 06 | 吳蘭 | 1992-03-01 | +--------+----------+------------+46. 查詢下個月過生日的學生。
知識點:日期和時間處理函數Month(),返回日期的月份
mysql> SELECT stu_id, stu_name, stu_birth-> FROM t_student-> WHERE Month(stu_birth) = Month(CurDate()) + 1;47. 查詢和“01”號學生所考課程完全相同的學生的信息。
知識點:GROUP_CONCAT()函數、自聯結、內部聯結、子查詢、COUNT()函數、GROUP BY分組、HAVING分組后過濾
**注意:**方法一實現效果較為全面;而方法二相較于13題添加了對課程數量的限制,主要依靠數據進行檢索,實現得不全面。
48. 查詢各科成績最高分、最低分和平均分。以如下形式顯示:課程編號、課程名稱、最高分、最低分、平均分、及格率、優秀率。(及格:>=60,優秀:>=90)
知識點:MAX()函數、MIN()函數、ROUND(x,d)函數、AVG()函數、SUM()函數、CASE WHEN 條件 THEN... ELSE... END、內部聯結
mysql> SELECT a.cou_id '編號', cou_name '名稱',-> MAX(stu_score) '最高分', MIN(stu_score) '最低分',-> ROUND(AVG(stu_score), 2) '平均分',-> ROUND(100 * (SUM(CASE WHEN stu_score >= 60 THEN 1 ELSE 0 END) / SUM(CASE WHEN stu_score THEN 1 ELSE 0 END)) ,2) '及格率',-> ROUND(100 * (SUM(CASE WHEN stu_score >= 90 THEN 1 ELSE 0 END) / SUM(CASE WHEN stu_score THEN 1 ELSE 0 END)) ,2) '優秀率'-> FROM t_course a-> LEFT OUTER JOIN t_score b ON a.cou_id = b.cou_id-> GROUP BY a.cou_id; +--------+--------+-----------+-----------+-----------+-----------+-----------+ | 編號 | 名稱 | 最高分 | 最低分 | 平均分 | 及格率 | 優秀率 | +--------+--------+-----------+-----------+-----------+-----------+-----------+ | 01 | 語文 | 80 | 31 | 64.50 | 66.67 | 0.00 | | 02 | 數學 | 90 | 30 | 72.67 | 83.33 | 16.67 | | 03 | 英語 | 99 | 20 | 68.50 | 66.67 | 33.33 | +--------+--------+-----------+-----------+-----------+-----------+-----------+49. 查詢所有學生的所有課程的成績以及平均成績。
知識點:ROUND(x,d)函數、AVG()函數、子查詢
mysql> SELECT a.stu_id '編號', stu_name '姓名',-> (SELECT stu_score FROM t_score WHERE cou_id = '01' AND stu_id = a.stu_id) '語文',-> (SELECT stu_score FROM t_score WHERE cou_id = '02' AND stu_id = a.stu_id) '數學',-> (SELECT stu_score FROM t_score WHERE cou_id = '03' AND stu_id = a.stu_id) '英語',-> (SELECT ROUND(AVG(stu_score),2) FROM t_score WHERE stu_id = a.stu_id GROUP BY stu_id) '平均分'-> FROM t_student a; +--------+--------+--------+--------+--------+-----------+ | 編號 | 姓名 | 語文 | 數學 | 英語 | 平均分 | +--------+--------+--------+--------+--------+-----------+ | 01 | 趙雷 | 80 | 90 | 99 | 89.67 | | 02 | 錢電 | 70 | 60 | 80 | 70.00 | | 03 | 孫風 | 80 | 80 | 80 | 80.00 | | 04 | 李云 | 50 | 30 | 20 | 33.33 | | 05 | 周梅 | 76 | 87 | NULL | 81.50 | | 06 | 吳蘭 | 31 | NULL | 34 | 32.50 | | 07 | 鄭竹 | NULL | 89 | 98 | 93.50 | | 08 | 王菊 | NULL | NULL | NULL | NULL | +--------+--------+--------+--------+--------+-----------+50. 查詢所有學生的課程及分數情況。
知識點:SUM()函數、CASE WHEN 條件 THEN... ELSE... END、GROUP BY分組、外部聯結(LEFT OUTER JOIN)
# 測試數據 mysql> SELECT stu_id,-> (CASE WHEN cou_name = '語文' THEN stu_score ELSE 0 END) 'Chinese',-> (CASE WHEN cou_name = '數學' THEN stu_score ELSE 0 END) 'Math',-> (CASE WHEN cou_name = '英語' THEN stu_score ELSE 0 END) 'English'-> FROM t_score a-> INNER JOIN t_course b ON a.cou_id = b.cou_id; +--------+---------+------+---------+ | stu_id | Chinese | Math | English | +--------+---------+------+---------+ | 01 | 80 | 0 | 0 | | 01 | 0 | 90 | 0 | | 01 | 0 | 0 | 99 | | 02 | 70 | 0 | 0 | | 02 | 0 | 60 | 0 | | 02 | 0 | 0 | 80 | | 03 | 80 | 0 | 0 | | 03 | 0 | 80 | 0 | | 03 | 0 | 0 | 80 | | 04 | 50 | 0 | 0 | | 04 | 0 | 30 | 0 | | 04 | 0 | 0 | 20 | | 05 | 76 | 0 | 0 | | 05 | 0 | 87 | 0 | | 06 | 31 | 0 | 0 | | 06 | 0 | 0 | 34 | | 07 | 0 | 89 | 0 | | 07 | 0 | 0 | 98 | +--------+---------+------+---------+mysql> SELECT a.stu_id, stu_name,-> SUM(CASE WHEN cou_name = '語文' THEN stu_score ELSE 0 END) 'Chinese',-> SUM(CASE WHEN cou_name = '數學' THEN stu_score ELSE 0 END) 'Math',-> SUM(CASE WHEN cou_name = '英語' THEN stu_score ELSE 0 END) 'English',-> SUM(stu_score) 'score_sum'-> FROM t_student a-> LEFT OUTER JOIN t_score b ON a.stu_id = b.stu_id-> LEFT OUTER JOIN t_course c ON b.cou_id = c.cou_id-> GROUP BY a.stu_id; +--------+----------+---------+------+---------+-----------+ | stu_id | stu_name | Chinese | Math | English | score_sum | +--------+----------+---------+------+---------+-----------+ | 01 | 趙雷 | 80 | 90 | 99 | 269 | | 02 | 錢電 | 70 | 60 | 80 | 210 | | 03 | 孫風 | 80 | 80 | 80 | 240 | | 04 | 李云 | 50 | 30 | 20 | 100 | | 05 | 周梅 | 76 | 87 | 0 | 163 | | 06 | 吳蘭 | 31 | 0 | 34 | 65 | | 07 | 鄭竹 | 0 | 89 | 98 | 187 | | 08 | 王菊 | 0 | 0 | 0 | NULL | +--------+----------+---------+------+---------+-----------+建表:
mysql> CREATE TABLE IF NOT EXISTS t_student(-> stu_id VARCHAR(20),-> stu_name VARCHAR(20) NOT NULL DEFAULT '',-> stu_birth VARCHAR(20) NOT NULL DEFAULT '',-> stu_sex VARCHAR(10) NOT NULL DEFAULT '',-> PRIMARY KEY(stu_id)); mysql> INSERT t_student VALUES-> ('01', '趙雷', '1990-01-01', '男'),-> ('02', '錢電', '1990-12-21', '男'),-> ('03', '孫風', '1990-05-20', '男'),-> ('04', '李云', '1990-08-06', '男'),-> ('05', '周梅', '1991-12-01', '女'),-> ('06', '吳蘭', '1992-03-01', '女'),-> ('07', '鄭竹', '1989-07-01', '女'),-> ('08', '王菊', '1990-01-20', '女');mysql> CREATE TABLE IF NOT EXISTS t_teacher(-> tea_id VARCHAR(20),-> tea_name VARCHAR(20) NOT NULL DEFAULT '',-> PRIMARY KEY(tea_id)); mysql> INSERT t_teacher VALUES-> ('01', '張三'),-> ('02', '李四'),-> ('03', '王五');mysql> CREATE TABLE IF NOT EXISTS t_course(-> cou_id VARCHAR(20),-> cou_name VARCHAR(20) NOT NULL DEFAULT '',-> tea_id VARCHAR(20) NOT NULL,-> PRIMARY KEY(cou_id)); mysql> INSERT t_course VALUES-> ('01', '語文', '02'),-> ('02', '數學', '01'),-> ('03', '英語', '03');mysql> CREATE TABLE IF NOT EXISTS t_score(-> stu_id VARCHAR(20),-> cou_id VARCHAR(20),-> stu_score INT(3),-> PRIMARY KEY(stu_id, cou_id))-> ; mysql> INSERT t_score VALUES-> ('01', '01', 80),-> ('01', '02', 90),-> ('01', '03', 99),-> ('02', '01', 70),-> ('02', '02', 60),-> ('02', '03', 80),-> ('03', '01', 80),-> ('03', '02', 80),-> ('03', '03', 80),-> ('04', '01', 50),-> ('04', '02', 30),-> ('04', '03', 20),-> ('05', '01', 76),-> ('05', '02', 87),-> ('06', '01', 31),-> ('06', '03', 34),-> ('07', '02', 89),-> ('07', '03', 98);參考鏈接:https://blog.csdn.net/fashion2014/article/details/78826299/
總結
以上是生活随笔為你收集整理的sql语句练习(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 004 排序(冒泡快排)
- 下一篇: sql语句练习(二):Demand