MySQL入门练习50题

一、表结构设计

1.数据库及表结构设计

sql 复制代码
-- 创建数据库
CREATE DATABASE IF NOT EXISTS school_db;
USE school_db;

-- 学生表(存储学生基本信息)
CREATE TABLE IF NOT EXISTS students
(
    student_id INT PRIMARY KEY COMMENT '学号(主键)',
    name       VARCHAR(50) NOT NULL COMMENT '姓名',
    gender     CHAR(1) COMMENT '性别(男/女)',
    age        INT COMMENT '年龄',
    class      VARCHAR(20) COMMENT '班级'
);

-- 教师表(存储教师基本信息)
CREATE TABLE IF NOT EXISTS teachers
(
    teacher_id INT PRIMARY KEY COMMENT '教师号(主键)',
    name       VARCHAR(50) NOT NULL COMMENT '姓名',
    gender     CHAR(1) COMMENT '性别(男/女)',
    department VARCHAR(50) COMMENT '所属部门'
);

-- 课程表(存储课程信息,关联教师)
CREATE TABLE IF NOT EXISTS courses
(
    course_id   INT PRIMARY KEY COMMENT '课程号(主键)',
    course_name VARCHAR(100) NOT NULL COMMENT '课程名',
    credits     DECIMAL(2, 1) COMMENT '学分',
    teacher_id  INT COMMENT '授课教师号(外键)',
    FOREIGN KEY (teacher_id) REFERENCES teachers (teacher_id)
);

-- 选课表(存储学生选课及成绩,关联学生和课程)
CREATE TABLE IF NOT EXISTS enrollments
(
    student_id  INT COMMENT '学号(外键)',
    course_id   INT COMMENT '课程号(外键)',
    score       DECIMAL(5, 2) COMMENT '成绩',
    enroll_date DATE COMMENT '选课日期',
    PRIMARY KEY (student_id, course_id), -- 联合主键(一个学生一门课只选一次)
    FOREIGN KEY (student_id) REFERENCES students (student_id),
    FOREIGN KEY (course_id) REFERENCES courses (course_id)
);

2.插入测试数据

sql 复制代码
-- 插入学生数据
INSERT INTO students (student_id, name, gender, age, class)
VALUES (1, '张三', '男', 19, '高一(1)班'),
       (2, '李四', '女', 18, '高一(1)班'),
       (3, '王五', '男', 17, '高一(2)班'),
       (4, '赵六', '女', 19, '高一(2)班'),
       (5, '孙七', '男', 18, '高一(3)班'),
       (6, '周八', '女', 17, '高一(3)班'),
       (7, '吴九', '男', 19, '高一(1)班'),
       (8, '郑十', '女', 18, '高一(2)班');

-- 插入教师数据
INSERT INTO teachers (teacher_id, name, gender, department)
VALUES (101, '王老师', '女', '数学组'),
       (102, '李老师', '男', '语文组'),
       (103, '张老师', '男', '英语组'),
       (104, '刘老师', '女', '物理组');

-- 插入课程数据
INSERT INTO courses (course_id, course_name, credits, teacher_id)
VALUES (1001, '数学', 3.0, 101),
       (1002, '语文', 2.5, 102),
       (1003, '英语', 3.0, 103),
       (1004, '物理', 2.0, 104),
       (1005, '化学', 2.0, 104);
-- 刘老师同时教物理和化学

-- 插入选课数据
INSERT INTO enrollments (student_id, course_id, score, enroll_date)
VALUES (1, 1001, 90.5, '2023-09-01'),
       (1, 1002, 85.0, '2023-09-01'),
       (1, 1003, 88.5, '2023-09-01'),
       (2, 1001, 82.0, '2023-09-01'),
       (2, 1002, 92.5, '2023-09-01'),
       (3, 1001, 76.0, '2023-09-01'),
       (3, 1003, 95.0, '2023-09-01'),
       (3, 1004, 80.5, '2023-09-01'),
       (4, 1002, 78.0, '2023-09-01'),
       (4, 1004, 89.0, '2023-09-01'),
       (5, 1001, 85.5, '2023-09-01'),
       (5, 1005, 91.0, '2023-09-01'),
       (6, 1003, 79.5, '2023-09-01'),
       (6, 1005, 86.0, '2023-09-01'),
       (7, 1001, 68.0, '2023-09-01'),
       (7, 1004, 72.5, '2023-09-01'),
       (8, 1002, 88.0, '2023-09-01'),
       (8, 1003, 93.0, '2023-09-01');

二、习题及答案

1.基础查询

sql 复制代码
-- 1.查询所有学生的姓名和年龄
SELECT name, age
FROM students;

-- 2.查询高一 (1) 班的所有学生信息
SELECT *
FROM students
WHERE class = '高一(1)班';

-- 3.查询年龄大于 18 岁的男生姓名和班级
SELECT name, class
FROM students
WHERE age > 18
  AND gender = '男';

-- 4.查询所有课程的名称和学分
SELECT course_name, credits
FROM courses;

-- 5.查询学分大于等于 3.0 的课程名称
SELECT course_name
FROM courses
WHERE credits >= 3.0;

-- 6.查询教师表中所有女教师的姓名和部门
SELECT name, department
FROM teachers
WHERE gender = '女';

-- 7.查询选课表中成绩在 80-90 分(含 80 和 90)的记录
SELECT *
FROM enrollments
WHERE score BETWEEN 80 AND 90;

-- 8.查询姓名以 "张" 开头的学生信息
SELECT *
FROM students
WHERE name LIKE '张%';

-- 9.查询班级包含 "(1)" 的学生姓名
SELECT name
FROM students
WHERE class LIKE '%(1)%';

-- 10.查询所有学生的学号、姓名,并按年龄从大到小排序
SELECT student_id, name
FROM students
ORDER BY age DESC;

2.多表连接查询

sql 复制代码
-- 11.查询每个学生的姓名及所选课程名称
SELECT s.name, c.course_name
FROM students s
         JOIN enrollments e ON s.student_id = e.student_id
         JOIN courses c ON e.course_id = c.course_id;

-- 12.查询 "数学" 课程的所有选课学生姓名和成绩
SELECT s.name, e.score
FROM students s
         JOIN enrollments e ON s.student_id = e.student_id
         JOIN courses c ON e.course_id = c.course_id
WHERE c.course_name = '数学';

-- 13.查询 "王老师" 教的所有课程名称
SELECT c.course_name
FROM courses c
         JOIN teachers t ON c.teacher_id = t.teacher_id
WHERE t.name = '王老师';

-- 14.查询每个学生的姓名、班级及所选课程的学分
SELECT s.name, s.class, c.credits
FROM students s
         JOIN enrollments e ON s.student_id = e.student_id
         JOIN courses c ON e.course_id = c.course_id;

-- 15.查询 "高一 (2) 班" 学生所选的课程名称及授课教师姓名
SELECT c.course_name, t.name
FROM students s
         JOIN enrollments e ON s.student_id = e.student_id
         JOIN courses c ON e.course_id = c.course_id
         JOIN teachers t ON c.teacher_id = t.teacher_id
WHERE s.class = '高一(2)班';

-- 16.查询所有学生的姓名及他们的选课日期(包括未选课的学生)
SELECT s.name, e.enroll_date
FROM students s
         LEFT JOIN enrollments e ON s.student_id = e.student_id;

-- 17.查询没有学生选的课程名称
SELECT c.course_name
FROM courses c
         LEFT JOIN enrollments e ON c.course_id = e.course_id
WHERE e.student_id IS NULL;

-- 18.查询 "英语" 课程成绩最高的学生姓名和成绩
SELECT s.name, e.score
FROM students s
         JOIN enrollments e ON s.student_id = e.student_id
         JOIN courses c ON e.course_id = c.course_id
WHERE c.course_name = '英语'
ORDER BY e.score DESC
LIMIT 1;

-- 19.查询 "李老师" 教的课程中,成绩大于 85 分的学生姓名
SELECT s.name
FROM students s
         JOIN enrollments e ON s.student_id = e.student_id
         JOIN courses c ON e.course_id = c.course_id
         JOIN teachers t ON c.teacher_id = t.teacher_id
WHERE t.name = '李老师'
  AND e.score > 85;

-- 20查询每个学生的姓名和所选课程的总分(按总分从高到低排序)
SELECT s.name, SUM(e.score) AS total_score
FROM students s
         JOIN enrollments e ON s.student_id = e.student_id
GROUP BY s.student_id, s.name
ORDER BY total_score DESC;

3.聚合与分组查询

sql 复制代码
-- 21.统计每个班级的学生人数
SELECT class, COUNT(*) AS student_count
FROM students
GROUP BY class;

-- 22.计算每门课程的平均成绩
SELECT c.course_name, AVG(e.score) AS avg_score
FROM courses c
         JOIN enrollments e ON c.course_id = e.course_id
GROUP BY c.course_id, c.course_name;

-- 23.统计每个教师所教课程的总学分
SELECT t.name, SUM(c.credits) AS total_credits
FROM teachers t
         JOIN courses c ON t.teacher_id = c.teacher_id
GROUP BY t.teacher_id, t.name;

-- 24.查询选课人数大于 3 人的课程名称和选课人数
SELECT c.course_name, COUNT(e.student_id) AS enroll_count
FROM courses c
         JOIN enrollments e ON c.course_id = e.course_id
GROUP BY c.course_id, c.course_name
HAVING enroll_count > 3;

-- 25.计算每个学生的选课门数
SELECT s.name, COUNT(e.course_id) AS course_count
FROM students s
         JOIN enrollments e ON s.student_id = e.student_id
GROUP BY s.student_id, s.name;

-- 26.查询平均成绩大于 85 分的课程名称和平均成绩
SELECT c.course_name, AVG(e.score) AS avg_score
FROM courses c
         JOIN enrollments e ON c.course_id = e.course_id
GROUP BY c.course_id, c.course_name
HAVING avg_score > 85;

-- 27.统计每个性别的学生人数
SELECT gender, COUNT(*) AS count
FROM students
GROUP BY gender;

-- 28.查询 "高一 (1) 班" 学生的平均年龄
SELECT AVG(age) AS avg_age
FROM students
WHERE class = '高一(1)班';

-- 29.计算每门课程的最高分和最低分
SELECT c.course_name, MAX(e.score) AS max_score, MIN(e.score) AS min_score
FROM courses c
         JOIN enrollments e ON c.course_id = e.course_id
GROUP BY c.course_id, c.course_name;

-- 30.统计每个部门的教师人数
SELECT department, COUNT(*) AS teacher_count
FROM teachers
GROUP BY department;

4.子查询

sql 复制代码
-- 31.查询与 "张三" 同班的学生姓名
SELECT name
FROM students
WHERE class = (SELECT class FROM students WHERE name = '张三')
  AND name != '张三';

-- 32.查询成绩高于 "数学" 课程平均成绩的学生姓名和成绩
SELECT s.name, e.score
FROM students s
         JOIN enrollments e ON s.student_id = e.student_id
WHERE e.course_id = (SELECT course_id FROM courses WHERE course_name = '数学')
  AND e.score >
      (SELECT AVG(score) FROM enrollments WHERE course_id = (SELECT course_id FROM courses WHERE course_name = '数学'));

-- 33.查询选修了 "物理" 课程的学生所在的班级
SELECT DISTINCT class
FROM students
WHERE student_id IN
      (SELECT student_id FROM enrollments WHERE course_id = (SELECT course_id FROM courses WHERE course_name = '物理'));

-- 34.查询没有选修 "语文" 课程的学生姓名
SELECT name
FROM students
WHERE student_id NOT IN
      (SELECT student_id FROM enrollments WHERE course_id = (SELECT course_id FROM courses WHERE course_name = '语文'));

-- 35.查询比 "高一 (1) 班" 所有学生年龄都小的学生姓名和年龄
SELECT name, age
FROM students
WHERE age < ALL (SELECT age FROM students WHERE class = '高一(1)班');

-- 36.查询至少选修了 "张三" 所选课程中一门的学生姓名
SELECT DISTINCT s.name
FROM students s
         JOIN enrollments e ON s.student_id = e.student_id
WHERE e.course_id IN
      (SELECT course_id FROM enrollments WHERE student_id = (SELECT student_id FROM students WHERE name = '张三'))
  AND s.name != '张三';

-- 37.查询 "英语" 成绩最高的学生姓名
SELECT name
FROM students
WHERE student_id = (SELECT student_id
                    FROM enrollments
                    WHERE course_id = (SELECT course_id FROM courses WHERE course_name = '英语')
                      AND score = (SELECT MAX(score)
                                   FROM enrollments
                                   WHERE course_id = (SELECT course_id FROM courses WHERE course_name = '英语')));

-- 38.查询教了 3 学分课程的教师姓名
SELECT name
FROM teachers
WHERE teacher_id IN (SELECT teacher_id FROM courses WHERE credits = 3.0);

-- 39.查询成绩不及格(<60 分)的学生姓名(若有)
SELECT s.name
FROM students s
         JOIN enrollments e ON s.student_id = e.student_id
WHERE e.score < 60;

-- 40查询选课门数超过 2 门的学生姓名
SELECT name
FROM students
WHERE student_id IN (SELECT student_id FROM enrollments GROUP BY student_id HAVING COUNT(course_id) > 2);

5.增删改操作

sql 复制代码
-- 41.新增一个学生:学号 9,姓名 "钱十一",女,17 岁,班级 "高一 (3) 班"
INSERT INTO students (student_id, name, gender, age, class)
VALUES (9, '钱十一', '女', 17, '高一(3)班');

-- 42.新增一门课程:课程号 1006,名称 "生物",学分 2.5,授课教师为 "张老师"
INSERT INTO courses (course_id, course_name, credits, teacher_id)
VALUES (1006, '生物', 2.5, (SELECT teacher_id FROM teachers WHERE name = '张老师'));

-- 43.为 "钱十一" 添加选课记录:选修 "生物",成绩 82 分,选课日期 2023-09-02
INSERT INTO enrollments (student_id, course_id, score, enroll_date)
VALUES (9, 1006, 82.0, '2023-09-02');

-- 44.将 "张三" 的年龄修改为 20 岁
UPDATE students
SET age = 20
WHERE name = '张三';

-- 45.将 "数学" 课程的学分修改为 3.5
UPDATE courses
SET credits = 3.5
WHERE course_name = '数学';

-- 46.将 "李四" 的 "语文" 成绩提高 5 分(原成绩 82.0→87.0)
UPDATE enrollments
SET score = score + 5
WHERE student_id = (SELECT student_id FROM students WHERE name = '李四')
  AND course_id = (SELECT course_id FROM courses WHERE course_name = '语文');

-- 47.删除 "郑十" 的 "英语" 选课记录
DELETE
FROM enrollments
WHERE student_id = (SELECT student_id FROM students WHERE name = '郑十')
  AND course_id = (SELECT course_id FROM courses WHERE course_name = '英语');

-- 48.删除 "化学" 课程的所有选课记录
DELETE
FROM enrollments
WHERE course_id = (SELECT course_id FROM courses WHERE course_name = '化学');

-- 49.删除学号为 7 的学生信息(需先删除其选课记录,否则外键约束报错)
DELETE
FROM enrollments
WHERE student_id = 7;
DELETE
FROM students
WHERE student_id = 7;

-- 50将 "物理组" 所有教师的性别修改为 "女"
UPDATE teachers
SET gender = '女'
WHERE department = '物理组';
相关推荐
小二·1 小时前
RAG + 向量数据库实战:ChromaDB / Milvus / FAISS 选型与性能横评
数据库·milvus·faiss
矜持的左手2 小时前
电子小白的枕边书:电子学(The Art of Electronics)
数据库·restful
吴声子夜歌2 小时前
Redis 5.x——布隆过滤器
数据库·redis·缓存
蓝天下的守望者2 小时前
svt_apb_if里的宏定义问题
运维·服务器·数据库
上海云盾-小余3 小时前
网站频繁遭遇 SQL 注入溯源与原生漏洞修复全流程总结
数据库·sql
数据库小学妹3 小时前
国家区域医疗中心国产化改造实战:数据库选型、跨院区数据互通与踩坑经验
数据库·国产数据库·数据库选型·医疗信息化·信创数据库·医疗信创
TPBoreas3 小时前
MySQL性能优化面试全攻略
mysql·面试·性能优化
xlq223224 小时前
11.表的内外连接,索引
mysql
AllData公司负责人4 小时前
数据库同步平台|AIIData数据中台实现OceanBase、达梦数据库、OpenGauss、人大金仓、Hive、TDengine 一键接入Doris
大数据·数据库·hive·mysql·oceanbase·tdengine