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 = '物理组';
相关推荐
@游子3 小时前
SQL注入语法和介绍(一)
数据库·oracle
蒋士峰DBA修行之路5 小时前
实验十三 WDR诊断报告
数据库
杂亿稿5 小时前
数据库的约束
数据库
u***32436 小时前
使用python进行PostgreSQL 数据库连接
数据库·python·postgresql
Codingwiz_Joy6 小时前
Day44 盲注、报错注入 & 实战复现
数据库·安全性测试
7***99877 小时前
GaussDB数据库中SQL诊断解析之配置SQL限流
数据库·sql·gaussdb
Wang's Blog9 小时前
MongoDB小课堂: 文档操作核心技术指南:主键机制、CRUD操作与最佳实践
数据库·mongodb
i***t9199 小时前
Linux下MySQL的简单使用
linux·mysql·adb
g***26799 小时前
最新SQL Server 2022保姆级安装教程【附安装包】
数据库·性能优化
风123456789~10 小时前
【OceanBase专栏】OB背景知识
数据库·笔记·oceanbase