当前位置: 首页 > news >正文

MySQL 经典练习 50 题(完美解答版,提供解题思路)

MySQL 经典练习 50 题(完美解答版)

  • MySQL 经典练习 50 题(完美解答版)
    • 一、数据库与表设计
      • 1. 创建数据库
      • 2. 创建表结构
        • (1)学生表(student)
        • (2)课程表(course)
        • (3)教师表(teacher)
        • (4)成绩表(score)
      • 3. 表关系说明
    • 二、插入样例数据
    • 三、经典练习50题及解答
      • 1. 查询"01"课程比"02"课程成绩高的学生的信息及课程分数
      • 2. 查询"01"课程比"02"课程成绩低的学生的信息及课程分数
      • 3. 查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩
      • 4. 查询平均成绩小于60分的同学的学生编号和学生姓名和平均成绩(包括有成绩的和无成绩的)
      • 5. 查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩
      • 6. 查询"李"姓老师的数量
      • 7. 查询学过"张三"老师授课的同学的信息
      • 8. 查询没学过"张三"老师授课的同学的信息
      • 9. 查询学过编号为"01"并且也学过编号为"02"的课程的同学的信息
      • 10. 查询学过编号为"01"但是没有学过编号为"02"的课程的同学的信息
      • 11. 查询没有学全所有课程的同学的信息
      • 12. 查询至少有一门课与学号为"01"的同学所学相同的同学的信息
      • 13. 查询和"01"号的同学学习的课程完全相同的其他同学的信息
      • 14. 查询没学过"张三"老师讲授的任一门课程的学生姓名
      • 15. 查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
      • 16. 检索"01"课程分数小于60,按分数降序排列的学生信息
      • 17. 按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
      • 18. 查询各科成绩最高分、最低分和平均分,以如下形式显示:课程ID,课程name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率
      • 19. 按各科成绩进行排序,并显示排名
      • 20. 查询学生的总成绩并进行排名
      • 21. 查询不同老师所教不同课程平均分从高到低显示
      • 22. 查询所有课程的成绩第2名到第3名的学生信息及该课程成绩
      • 23. 统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[0-60]及所占百分比
      • 24. 查询学生平均成绩及其名次
      • 25. 查询各科成绩前三名的记录
      • 26. 查询每门课程被选修的学生数
      • 27. 查询出只有两门课程的全部学生的学号和姓名
      • 28. 查询男生、女生人数
      • 29. 查询名字中含有"风"字的学生信息
      • 30. 查询同名同性学生名单,并统计同名人数
      • 31. 查询1990年出生的学生名单
      • 32. 查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列
      • 33. 查询平均成绩大于等于85的所有学生的学号、姓名和平均成绩
      • 34. 查询课程名称为"数学",且分数低于60的学生姓名和分数
      • 35. 查询所有学生的课程及分数情况(即学生-课程成绩矩阵)
      • 36. 查询任何一门课程成绩在70分以上的学生姓名、课程名称和分数
      • 37. 查询课程不及格的学生
      • 38. 查询课程编号为01且课程成绩在80分以上的学生的学号和姓名
      • 39. 求每门课程的学生人数
      • 40. 查询选修"张三"老师所授课程的学生中,成绩最高的学生信息及其成绩
      • 41. 查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩
      • 42. 查询每门课程成绩最好的前三名
      • 43. 统计每门课程的学生选修人数(超过5人的课程才统计)
      • 44. 检索至少选修两门课程的学生学号
      • 45. 查询选修了全部课程的学生信息
      • 46. 查询各学生的年龄(周岁)
      • 47. 查询本周过生日的学生
      • 48. 查询下周过生日的学生
      • 49. 查询本月过生日的学生
      • 50. 查询12月份过生日的学生

一、数据库与表设计

为完成以下练习,我们需要创建一个包含学生、课程、教师、成绩信息的数据库,以及对应的4张表。

1. 创建数据库

首先创建名为 school 的数据库:

CREATE DATABASE IF NOT EXISTS school;
USE school;

2. 创建表结构

(1)学生表(student)

存储学生的基本信息,包括学号、姓名、性别、出生年月。

CREATE TABLE IF NOT EXISTS student (s_id VARCHAR(20) PRIMARY KEY,  -- 学生编号s_name VARCHAR(20) NOT NULL,   -- 学生姓名s_sex VARCHAR(10) NOT NULL,    -- 性别(男/女)s_birth DATE NOT NULL          -- 出生年月
);
(2)课程表(course)

存储课程信息,包括课程编号、课程名、授课教师编号。

CREATE TABLE IF NOT EXISTS course (c_id VARCHAR(20) PRIMARY KEY,  -- 课程编号c_name VARCHAR(20) NOT NULL,   -- 课程名称t_id VARCHAR(20) NOT NULL      -- 教师编号(关联教师表)
);
(3)教师表(teacher)

存储教师信息,包括教师编号、教师姓名。

CREATE TABLE IF NOT EXISTS teacher (t_id VARCHAR(20) PRIMARY KEY,  -- 教师编号t_name VARCHAR(20) NOT NULL    -- 教师姓名
);
(4)成绩表(score)

存储学生的课程成绩,包括学号、课程编号、成绩(可空,代表未选课或未考试)。

CREATE TABLE IF NOT EXISTS score (s_id VARCHAR(20) NOT NULL,     -- 学生编号(关联学生表)c_id VARCHAR(20) NOT NULL,     -- 课程编号(关联课程表)s_score DECIMAL(5,2),          -- 成绩(保留2位小数)PRIMARY KEY (s_id, c_id)       -- 联合主键(一个学生一门课只有一个成绩)
);

3. 表关系说明

  • 学生表(student)与成绩表(score):一对多关系(一个学生可有多门课成绩),通过 s_id 关联。
  • 课程表(course)与成绩表(score):一对多关系(一门课程可有多个学生成绩),通过 c_id 关联。
  • 教师表(teacher)与课程表(course):一对多关系(一个教师可教多门课程),通过 t_id 关联。

二、插入样例数据

为方便练习,我们插入以下样例数据(覆盖不同场景:成绩高低、及格/不及格、同名学生、不同性别等)。

-- 插入学生数据
INSERT INTO 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'),
('09', '赵雷', '男', '1990-02-01');  -- 同名同性学生-- 插入教师数据
INSERT INTO teacher VALUES
('01', '张三'),
('02', '李四'),
('03', '王五');-- 插入课程数据(关联教师)
INSERT INTO course VALUES
('01', '语文', '02'),    -- 李四教语文
('02', '数学', '01'),    -- 张三教数学
('03', '英语', '03'),    -- 王五教英语
('04', '物理', '01');    -- 张三教物理-- 插入成绩数据(包含不及格、NULL(未选课)等情况)
INSERT INTO score VALUES
('01', '01', 80),    -- 赵雷-语文-80
('01', '02', 90),    -- 赵雷-数学-90
('01', '03', 99),    -- 赵雷-英语-99
('02', '01', 70),    -- 钱电-语文-70
('02', '02', 60),    -- 钱电-数学-60
('02', '03', 80),    -- 钱电-英语-80
('03', '01', 80),    -- 孙风-语文-80
('03', '02', 80),    -- 孙风-数学-80
('03', '03', 80),    -- 孙风-英语-80
('04', '01', 50),    -- 李云-语文-50(不及格)
('04', '02', 30),    -- 李云-数学-30(不及格)
('05', '01', 90),    -- 周梅-语文-90
('05', '02', 90),    -- 周梅-数学-90
('06', '03', 50),    -- 吴兰-英语-50(不及格)
('07', '02', 100),   -- 郑竹-数学-100
('07', '04', 80),    -- 郑竹-物理-80
('08', '03', 90),    -- 王菊-英语-90
('09', '02', 60);    -- 赵雷(同名)-数学-60

三、经典练习50题及解答

1. 查询"01"课程比"02"课程成绩高的学生的信息及课程分数

思路:通过成绩表自连接,分别获取学生的01课程和02课程成绩,再关联学生表筛选符合条件的记录。

SELECT s.*, sc1.s_score AS '01课程分数', sc2.s_score AS '02课程分数'
FROM student s
JOIN score sc1 ON s.s_id = sc1.s_id AND sc1.c_id = '01'  -- 01课程成绩
JOIN score sc2 ON s.s_id = sc2.s_id AND sc2.c_id = '02'  -- 02课程成绩
WHERE sc1.s_score > sc2.s_score;

2. 查询"01"课程比"02"课程成绩低的学生的信息及课程分数

思路:与第1题类似,仅条件改为01课程成绩 < 02课程成绩。

SELECT s.*, sc1.s_score AS '01课程分数', sc2.s_score AS '02课程分数'
FROM student s
JOIN score sc1 ON s.s_id = sc1.s_id AND sc1.c_id = '01'
JOIN score sc2 ON s.s_id = sc2.s_id AND sc2.c_id = '02'
WHERE sc1.s_score < sc2.s_score;

3. 查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩

思路:按学生分组计算平均成绩,用HAVING筛选平均成绩≥60的记录。

SELECT s.s_id, s.s_name, AVG(sc.s_score) AS 平均成绩
FROM student s
JOIN score sc ON s.s_id = sc.s_id
GROUP BY s.s_id, s.s_name
HAVING 平均成绩 >= 60;

4. 查询平均成绩小于60分的同学的学生编号和学生姓名和平均成绩(包括有成绩的和无成绩的)

思路:用左连接保留所有学生(包括无成绩的),用IFNULL将NULL成绩转为0,再筛选平均成绩<60的记录。

SELECT s.s_id, s.s_name, AVG(IFNULL(sc.s_score, 0)) AS 平均成绩  -- 无成绩按0计算
FROM student s
LEFT JOIN score sc ON s.s_id = sc.s_id
GROUP BY s.s_id, s.s_name
HAVING 平均成绩 < 60;

5. 查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩

思路:按学生分组,用COUNT统计选课数(排除NULL),用SUM计算总成绩(NULL按0处理)。

SELECT s.s_id, s.s_name, COUNT(sc.c_id) AS 选课总数,  -- 统计选课数(NULL不计数)SUM(IFNULL(sc.s_score, 0)) AS 总成绩  -- 无成绩按0计算
FROM student s
LEFT JOIN score sc ON s.s_id = sc.s_id
GROUP BY s.s_id, s.s_name;

6. 查询"李"姓老师的数量

思路:用LIKE匹配姓氏为“李”的教师,统计数量。

SELECT COUNT(t_id) AS 李姓老师数量
FROM teacher
WHERE t_name LIKE '李%';

7. 查询学过"张三"老师授课的同学的信息

思路:通过教师表→课程表→成绩表关联,筛选张三教的课程对应的学生。

SELECT DISTINCT s.*  -- 去重(避免同一学生选多门张三的课)
FROM student s
JOIN score sc ON s.s_id = sc.s_id
JOIN course c ON sc.c_id = c.c_id
JOIN teacher t ON c.t_id = t.t_id
WHERE t.t_name = '张三';

8. 查询没学过"张三"老师授课的同学的信息

思路:先找到学过张三课程的学生ID,再用NOT IN筛选不在其中的学生。

SELECT *
FROM student
WHERE s_id NOT IN (SELECT DISTINCT sc.s_idFROM score scJOIN course c ON sc.c_id = c.c_idJOIN teacher t ON c.t_id = t.t_idWHERE t.t_name = '张三'
);

9. 查询学过编号为"01"并且也学过编号为"02"的课程的同学的信息

思路:用成绩表自连接,筛选同时有01和02课程成绩的学生。

SELECT s.*
FROM student s
JOIN score sc1 ON s.s_id = sc1.s_id AND sc1.c_id = '01'
JOIN score sc2 ON s.s_id = sc2.s_id AND sc2.c_id = '02';

10. 查询学过编号为"01"但是没有学过编号为"02"的课程的同学的信息

思路:先找到学过01课程的学生,再排除学过02课程的学生。

SELECT s.*
FROM student s
JOIN score sc1 ON s.s_id = sc1.s_id AND sc1.c_id = '01'
LEFT JOIN score sc2 ON s.s_id = sc2.s_id AND sc2.c_id = '02'
WHERE sc2.s_id IS NULL;  -- 没有02课程成绩

11. 查询没有学全所有课程的同学的信息

思路:先统计总课程数,再筛选选课数小于总课程数的学生。

-- 总课程数
SET @total_course = (SELECT COUNT(*) FROM course);SELECT s.*
FROM student s
LEFT JOIN score sc ON s.s_id = sc.s_id
GROUP BY s.s_id, s.s_name
HAVING COUNT(DISTINCT sc.c_id) < @total_course;

12. 查询至少有一门课与学号为"01"的同学所学相同的同学的信息

思路:先找到01号学生学过的课程,再筛选学过这些课程的其他学生。

SELECT DISTINCT s.*
FROM student s
JOIN score sc ON s.s_id = sc.s_id
WHERE sc.c_id IN (SELECT c_id FROM score WHERE s_id = '01'  -- 01号学生学过的课程
) AND s.s_id != '01';  -- 排除01号自身

13. 查询和"01"号的同学学习的课程完全相同的其他同学的信息

思路:筛选与01号学生选课数量相同,且所有课程都重合的学生。

-- 01号学生的选课数
SET @01_course_count = (SELECT COUNT(*) FROM score WHERE s_id = '01');SELECT s.*
FROM student s
WHERE s.s_id != '01'  -- 排除01号自身
AND (SELECT COUNT(*) FROM score WHERE s_id = s.s_id) = @01_course_count  -- 选课数相同
AND NOT EXISTS (-- 不存在01号学过但该学生没学过的课程SELECT c_id FROM score WHERE s_id = '01'EXCEPTSELECT c_id FROM score WHERE s_id = s.s_id
);

14. 查询没学过"张三"老师讲授的任一门课程的学生姓名

思路:先找到张三教的课程,再筛选没学过这些课程的学生。

SELECT s_name
FROM student
WHERE s_id NOT IN (SELECT DISTINCT sc.s_idFROM score scJOIN course c ON sc.c_id = c.c_idJOIN teacher t ON c.t_id = t.t_idWHERE t.t_name = '张三'
);

15. 查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩

思路:筛选成绩<60的记录,按学生分组统计不及格课程数≥2,再计算平均成绩。

SELECT s.s_id, s.s_name, AVG(sc.s_score) AS 平均成绩
FROM student s
JOIN score sc ON s.s_id = sc.s_id
WHERE sc.s_score < 60  -- 仅统计不及格成绩
GROUP BY s.s_id, s.s_name
HAVING COUNT(sc.c_id) >= 2;  -- 不及格课程≥2门

16. 检索"01"课程分数小于60,按分数降序排列的学生信息

思路:筛选01课程且成绩<60的记录,按分数降序排序。

SELECT s.*, sc.s_score
FROM student s
JOIN score sc ON s.s_id = sc.s_id
WHERE sc.c_id = '01' AND sc.s_score < 60
ORDER BY sc.s_score DESC;

17. 按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩

思路:用窗口函数AVG()计算每个学生的平均成绩(无需分组),按平均成绩排序。

SELECT s.s_id, s.s_name, sc.c_id, sc.s_score,AVG(sc.s_score) OVER (PARTITION BY s.s_id) AS 平均成绩  -- 按学生分组计算平均
FROM student s
LEFT JOIN score sc ON s.s_id = sc.s_id
ORDER BY 平均成绩 DESC;

18. 查询各科成绩最高分、最低分和平均分,以如下形式显示:课程ID,课程name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率

(注:及格≥60,中等≥70,优良≥80,优秀≥90)

SELECT c.c_id,c.c_name,MAX(sc.s_score) AS 最高分,MIN(sc.s_score) AS 最低分,AVG(sc.s_score) AS 平均分,-- 及格率(≥60)ROUND(SUM(CASE WHEN sc.s_score >= 60 THEN 1 ELSE 0 END) / COUNT(*) * 100, 2) AS 及格率(%),-- 中等率(≥70)ROUND(SUM(CASE WHEN sc.s_score >= 70 THEN 1 ELSE 0 END) / COUNT(*) * 100, 2) AS 中等率(%),-- 优良率(≥80)ROUND(SUM(CASE WHEN sc.s_score >= 80 THEN 1 ELSE 0 END) / COUNT(*) * 100, 2) AS 优良率(%),-- 优秀率(≥90)ROUND(SUM(CASE WHEN sc.s_score >= 90 THEN 1 ELSE 0 END) / COUNT(*) * 100, 2) AS 优秀率(%)
FROM course c
JOIN score sc ON c.c_id = sc.c_id
GROUP BY c.c_id, c.c_name;

19. 按各科成绩进行排序,并显示排名

思路:用窗口函数RANK()按课程分组排序(相同成绩排名相同,后续排名跳空)。

SELECT sc.s_id,sc.c_id,sc.s_score,RANK() OVER (PARTITION BY sc.c_id ORDER BY sc.s_score DESC) AS 排名
FROM score sc;

20. 查询学生的总成绩并进行排名

思路:先计算每个学生的总成绩,再用RANK()排名。

SELECT s_id,总成绩,RANK() OVER (ORDER BY 总成绩 DESC) AS 排名
FROM (SELECT s_id, SUM(s_score) AS 总成绩 FROM score GROUP BY s_id
) AS total;

21. 查询不同老师所教不同课程平均分从高到低显示

思路:关联教师、课程、成绩表,按教师和课程分组计算平均分,按平均分降序排序。

SELECT t.t_id,t.t_name,c.c_id,c.c_name,AVG(sc.s_score) AS 平均分
FROM teacher t
JOIN course c ON t.t_id = c.t_id
JOIN score sc ON c.c_id = sc.c_id
GROUP BY t.t_id, t.t_name, c.c_id, c.c_name
ORDER BY 平均分 DESC;

22. 查询所有课程的成绩第2名到第3名的学生信息及该课程成绩

思路:用窗口函数RANK()获取各科排名,再筛选排名为2或3的记录。

SELECT s.s_id,s.s_name,r.c_id,r.s_score,r.排名
FROM (SELECT sc.*,RANK() OVER (PARTITION BY sc.c_id ORDER BY sc.s_score DESC) AS 排名FROM score sc
) AS r
JOIN student s ON r.s_id = s.s_id
WHERE r.排名 BETWEEN 2 AND 3;

23. 统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[0-60]及所占百分比

SELECT c.c_id,c.c_name,-- 100-85分人数及百分比SUM(CASE WHEN sc.s_score BETWEEN 85 AND 100 THEN 1 ELSE 0 END) AS '[100-85]',ROUND(SUM(CASE WHEN sc.s_score BETWEEN 85 AND 100 THEN 1 ELSE 0 END)/COUNT(*)*100,2) AS '[100-85]%',-- 85-70分人数及百分比SUM(CASE WHEN sc.s_score BETWEEN 70 AND 84 THEN 1 ELSE 0 END) AS '[85-70]',ROUND(SUM(CASE WHEN sc.s_score BETWEEN 70 AND 84 THEN 1 ELSE 0 END)/COUNT(*)*100,2) AS '[85-70]%',-- 70-60分人数及百分比SUM(CASE WHEN sc.s_score BETWEEN 60 AND 69 THEN 1 ELSE 0 END) AS '[70-60]',ROUND(SUM(CASE WHEN sc.s_score BETWEEN 60 AND 69 THEN 1 ELSE 0 END)/COUNT(*)*100,2) AS '[70-60]%',-- 0-60分人数及百分比SUM(CASE WHEN sc.s_score < 60 THEN 1 ELSE 0 END) AS '[0-60]',ROUND(SUM(CASE WHEN sc.s_score < 60 THEN 1 ELSE 0 END)/COUNT(*)*100,2) AS '[0-60]%'
FROM course c
JOIN score sc ON c.c_id = sc.c_id
GROUP BY c.c_id, c.c_name;

24. 查询学生平均成绩及其名次

思路:计算每个学生的平均成绩,用RANK()排名。

SELECT s_id,平均成绩,RANK() OVER (ORDER BY 平均成绩 DESC) AS 名次
FROM (SELECT s_id, AVG(s_score) AS 平均成绩 FROM score GROUP BY s_id
) AS avg_score;

25. 查询各科成绩前三名的记录

思路:用窗口函数ROW_NUMBER()按课程分组排序,取前3名(若有并列成绩,ROW_NUMBER会强制排序,RANK可能返回更多)。

SELECT c_id,s_id,s_score,排名
FROM (SELECT *,ROW_NUMBER() OVER (PARTITION BY c_id ORDER BY s_score DESC) AS 排名FROM score
) AS r
WHERE 排名 <= 3;

26. 查询每门课程被选修的学生数

思路:按课程分组,统计学生数(去重,避免同一学生重复计数)。

SELECT c_id, COUNT(DISTINCT s_id) AS 选修学生数
FROM score
GROUP BY c_id;

27. 查询出只有两门课程的全部学生的学号和姓名

思路:按学生分组,统计选课数=2的学生。

SELECT s.s_id, s.s_name
FROM student s
JOIN score sc ON s.s_id = sc.s_id
GROUP BY s.s_id, s.s_name
HAVING COUNT(sc.c_id) = 2;

28. 查询男生、女生人数

思路:按性别分组统计人数。

SELECT s_sex, COUNT(s_id) AS 人数
FROM student
GROUP BY s_sex;

29. 查询名字中含有"风"字的学生信息

思路:用LIKE匹配包含“风”的姓名。

SELECT *
FROM student
WHERE s_name LIKE '%风%';

30. 查询同名同性学生名单,并统计同名人数

思路:按姓名和性别分组,筛选人数>1的组。

SELECT s_name, s_sex, COUNT(*) AS 同名人数
FROM student
GROUP BY s_name, s_sex
HAVING COUNT(*) > 1;

31. 查询1990年出生的学生名单

思路:用YEAR()函数提取出生年份,筛选=1990的记录。

SELECT *
FROM student
WHERE YEAR(s_birth) = 1990;

32. 查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列

思路:按课程分组计算平均分,用ORDER BY指定排序规则。

SELECT c_id, AVG(s_score) AS 平均成绩
FROM score
GROUP BY c_id
ORDER BY 平均成绩 DESC, c_id ASC;

33. 查询平均成绩大于等于85的所有学生的学号、姓名和平均成绩

思路:按学生分组计算平均分,筛选≥85的记录。

SELECT s.s_id, s.s_name, AVG(sc.s_score) AS 平均成绩
FROM student s
JOIN score sc ON s.s_id = sc.s_id
GROUP BY s.s_id, s.s_name
HAVING 平均成绩 >= 85;

34. 查询课程名称为"数学",且分数低于60的学生姓名和分数

思路:关联课程表和成绩表,筛选课程名为“数学”且成绩<60的记录。

SELECT s.s_name, sc.s_score
FROM student s
JOIN score sc ON s.s_id = sc.s_id
JOIN course c ON sc.c_id = c.c_id
WHERE c.c_name = '数学' AND sc.s_score < 60;

35. 查询所有学生的课程及分数情况(即学生-课程成绩矩阵)

思路:用CASE WHEN将课程成绩转为列(适合课程数量固定的场景)。

SELECT s.s_id,s.s_name,MAX(CASE WHEN c.c_name = '语文' THEN sc.s_score END) AS 语文,MAX(CASE WHEN c.c_name = '数学' THEN sc.s_score END) AS 数学,MAX(CASE WHEN c.c_name = '英语' THEN sc.s_score END) AS 英语,MAX(CASE WHEN c.c_name = '物理' THEN sc.s_score END) AS 物理
FROM student s
LEFT JOIN score sc ON s.s_id = sc.s_id
LEFT JOIN course c ON sc.c_id = c.c_id
GROUP BY s.s_id, s.s_name;

36. 查询任何一门课程成绩在70分以上的学生姓名、课程名称和分数

思路:直接筛选成绩>70的记录,关联学生和课程表。

SELECT s.s_name, c.c_name, sc.s_score
FROM student s
JOIN score sc ON s.s_id = sc.s_id
JOIN course c ON sc.c_id = c.c_id
WHERE sc.s_score > 70;

37. 查询课程不及格的学生

思路:筛选成绩<60的记录,关联学生和课程表。

SELECT s.s_id, s.s_name, c.c_name, sc.s_score
FROM student s
JOIN score sc ON s.s_id = sc.s_id
JOIN course c ON sc.c_id = c.c_id
WHERE sc.s_score < 60;

38. 查询课程编号为01且课程成绩在80分以上的学生的学号和姓名

思路:筛选课程01且成绩>80的记录,关联学生表。

SELECT s.s_id, s.s_name
FROM student s
JOIN score sc ON s.s_id = sc.s_id
WHERE sc.c_id = '01' AND sc.s_score > 80;

39. 求每门课程的学生人数

思路:与第26题相同,按课程分组统计学生数。

SELECT c_id, COUNT(DISTINCT s_id) AS 学生人数
FROM score
GROUP BY c_id;

40. 查询选修"张三"老师所授课程的学生中,成绩最高的学生信息及其成绩

思路:先找到张三教的课程,再筛选这些课程中成绩最高的记录。

SELECT s.*, sc.s_score, c.c_name
FROM student s
JOIN score sc ON s.s_id = sc.s_id
JOIN course c ON sc.c_id = c.c_id
JOIN teacher t ON c.t_id = t.t_id
WHERE t.t_name = '张三'
AND sc.s_score = (-- 张三所授课程的最高成绩SELECT MAX(sc2.s_score)FROM score sc2JOIN course c2 ON sc2.c_id = c2.c_idJOIN teacher t2 ON c2.t_id = t2.t_idWHERE t2.t_name = '张三'
);

41. 查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩

思路:成绩表自连接,筛选不同课程但成绩相同的记录。

SELECT DISTINCT sc1.s_id, sc1.c_id, sc1.s_score
FROM score sc1
JOIN score sc2 ON sc1.s_score = sc2.s_score 
AND sc1.c_id != sc2.c_id  -- 不同课程
AND sc1.s_id = sc2.s_id;  -- 同一学生

42. 查询每门课程成绩最好的前三名

思路:与第25题相同,用窗口函数取每门课程前3名。

SELECT c_id,s_id,s_score,排名
FROM (SELECT *,ROW_NUMBER() OVER (PARTITION BY c_id ORDER BY s_score DESC) AS 排名FROM score
) AS r
WHERE 排名 <= 3;

43. 统计每门课程的学生选修人数(超过5人的课程才统计)

思路:按课程分组统计人数,用HAVING筛选人数>5的课程。

SELECT c_id, COUNT(DISTINCT s_id) AS 选修人数
FROM score
GROUP BY c_id
HAVING 选修人数 > 5;

44. 检索至少选修两门课程的学生学号

思路:按学生分组,统计选课数≥2的学生。

SELECT s_id
FROM score
GROUP BY s_id
HAVING COUNT(c_id) >= 2;

45. 查询选修了全部课程的学生信息

思路:筛选选课数等于总课程数的学生。

-- 总课程数
SET @total_course = (SELECT COUNT(*) FROM course);SELECT s.*
FROM student s
JOIN score sc ON s.s_id = sc.s_id
GROUP BY s.s_id, s.s_name
HAVING COUNT(DISTINCT sc.c_id) = @total_course;

46. 查询各学生的年龄(周岁)

思路:用TIMESTAMPDIFF计算当前日期与出生日期的年份差(当前日期用CURDATE())。

SELECT s_id,s_name,TIMESTAMPDIFF(YEAR, s_birth, CURDATE()) AS 年龄
FROM student;

47. 查询本周过生日的学生

思路:用WEEKOFYEAR()获取生日所在周,与当前周对比(注意:每年的周数可能跨年份,需统一按“今年的生日”计算)。

SELECT *
FROM student
WHERE WEEKOFYEAR(DATE_FORMAT(s_birth, CONCAT(YEAR(CURDATE()), '-%m-%d'))) = WEEKOFYEAR(CURDATE());

48. 查询下周过生日的学生

思路:与第47题类似,筛选生日所在周=当前周+1。

SELECT *
FROM student
WHERE WEEKOFYEAR(DATE_FORMAT(s_birth, CONCAT(YEAR(CURDATE()), '-%m-%d'))) = WEEKOFYEAR(CURDATE()) + 1;

49. 查询本月过生日的学生

思路:用MONTH()提取生日月份,与当前月份对比。

SELECT *
FROM student
WHERE MONTH(s_birth) = MONTH(CURDATE());

50. 查询12月份过生日的学生

思路:筛选生日月份=12的学生。

SELECT *
FROM student
WHERE MONTH(s_birth) = 12;
http://www.dtcms.com/a/326118.html

相关文章:

  • Spring Framework源码解析——DisposableBean
  • Oracle数据库中的Library cache lock和pin介绍
  • Java多线程并发控制:使用ReentrantLock实现生产者-消费者模型
  • js异步操作 Promise :fetch API 带来的网络请求变革—仙盟创梦IDE
  • 机器翻译:Bahdanau注意力和Luong注意力详解
  • 【浮点数存储】double类型注意点
  • 理解LangChain — Part 3:链式工作流与输出解析器
  • Notepad--:国产跨平台文本编辑器,Notepad++ 的理想替代方案
  • 写一篇Ping32和IP-Guard的对比,重点突出Ping32
  • 循环控制:break和continue用法
  • 鸿蒙flutter项目接入极光推送
  • Java项目基本流程(三)
  • Orange的运维学习日记--38.MariaDB详解与服务部署
  • linux安装和使用git
  • Elasticsearch 官方 Node.js 从零到生产
  • docker部署elasticsearch-8.11.1
  • 网络的基本概念、通信原理以及网络安全问题
  • YOLOv6深度解析:实时目标检测的新突破
  • 时序数据库为什么选IoTDB?
  • 爬虫与数据分析结合案例
  • STM32 HAL驱动MPU6050传感器
  • p6spy和p6spy-spring-boot-starter的SpringBoot3集成配置
  • 高性能Web服务器
  • java基础概念(二)----变量(附练习题)
  • Go 语言三大核心数据结构深度解析:数组、切片(Slice)与映射(Map)
  • Unity插件DOTween使用
  • 【GPT入门】第45课 无梯子,linux/win下载huggingface模型方法
  • 如何避免团队文件同步过程中版本信息的丢失?
  • GAI 与 Tesla 机器人的具体联动机制
  • 变频器与伺服系统的工作原理,干扰来源及治理方式