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

SQL从入门到起飞:完整数据库操作练习

可以先看上篇文章,包含对数据库创建、表创建、表数据插入。SQL查询从入门到起飞。
SQL从入门到起飞:完整学习数据库与100+练习题
下面我将补充数据库操作(DDL、DML)的练习题目,包括创建数据库、表、插入、更新、删除等操作。

DDL(数据定义语言)练习

数据库操作

  1. 创建一个名为university_db的数据库
  2. 查看所有数据库列表
  3. 切换到university_db数据库
  4. 删除university_db数据库(练习后恢复)

表操作

  1. 创建一个faculty表,包含字段:faculty_id(主键), faculty_name, dean_name, established_year
  2. 修改students表,添加一个phone_number字段
  3. 修改students表,将scholarship字段改为DECIMAL(10,2)
  4. teachers表添加一个索引在department_id字段上
  5. 创建一个course_prerequisites表来管理课程先修关系
  6. library表添加一个唯一约束在isbn字段上
  7. 创建一个视图student_course_grades,显示学生姓名、课程名称和成绩
  8. 创建一个存储过程get_student_info,根据学生ID返回学生信息
  9. 创建一个触发器,在删除学生前检查是否有相关记录
  10. scores表添加检查约束,确保成绩在0-100之间
  11. 创建一个临时表存储成绩优秀的学生信息

DML(数据操作语言)练习

插入操作

  1. faculty表插入3个学院的数据
  2. students表插入5名新学生的数据
  3. teachers表插入3名新教师的数据
  4. courses表插入2门新课程的数据
  5. enrollments表插入10条选课记录
  6. scores表插入相应的成绩记录
  7. 使用INSERT…SELECT语句将计算机系学生复制到一个新表
  8. 批量插入多条图书馆藏书记录
  9. 插入一条借阅记录,包括借书和预计归还日期
  10. 使用多行插入语法一次性插入多个社团信息

更新操作

  1. 将所有教师的工资增加10%
  2. 将计算机系学生的奖学金增加1000元
  3. 将"数据库系统"课程的成绩全部提高5分(不超过100分)
  4. 更新所有逾期未还书的罚款金额(每天0.5元)
  5. 将2022年入学学生的院系改为新成立的"人工智能"系
  6. 将所有教授的职称更新为"正教授"
  7. 将没有投影仪的教室添加投影仪设备
  8. 将选修了"Java程序设计"且成绩低于60分的学生成绩改为60分
  9. 将所有社团的预算增加20%
  10. 将年龄大于20岁的学生的奖学金减少500元

删除操作

  1. 删除所有成绩为0的记录
  2. 删除没有学生选修的课程
  3. 删除借阅记录中已归还且无罚款的记录
  4. 删除没有成员参加的社团
  5. 删除2023年之前的所有活动记录
  6. 使用事务删除一个学生及其所有相关记录
  7. 删除重复的选课记录(同一学生同一课程多次选课)
  8. 删除没有安排教室的课程安排记录
  9. 删除可用副本数为0的图书记录
  10. 删除工资低于平均工资的教师记录

综合操作练习

  1. 创建一个新表alumni,并将已毕业学生的数据转移至此表
  2. 使用MERGE语句同步学生表和校友表的数据
  3. 使用CASE语句更新学生奖学金等级(90分以上A等,80-89分B等,其他C等)
  4. 使用事务处理借书操作(减少可用副本数,添加借阅记录)
  5. 使用游标遍历所有学生并更新其年龄字段
  6. 创建一个函数计算学生的GPA(平均学分绩点)
  7. 创建一个存储过程用于分页查询学生信息
  8. 使用临时表统计每个院系的学生成绩分布
  9. 使用公用表表达式(CTE)查询学生的选课路径
  10. 使用窗口函数计算每个学生的成绩排名

完整示例代码

DDL操作示例

-- 1. 创建数据库
CREATE DATABASE IF NOT EXISTS university_db;
USE university_db;-- 5. 创建院系表
CREATE TABLE faculty (faculty_id INT PRIMARY KEY AUTO_INCREMENT,faculty_name VARCHAR(100) NOT NULL,dean_name VARCHAR(100),established_year INT
);-- 6. 修改学生表添加电话号码字段
ALTER TABLE students ADD COLUMN phone_number VARCHAR(15);-- 7. 修改学生表奖学金字段类型
ALTER TABLE students MODIFY COLUMN scholarship DECIMAL(10,2);-- 9. 创建课程先修关系表
CREATE TABLE course_prerequisites (prerequisite_id INT PRIMARY KEY AUTO_INCREMENT,course_id INT NOT NULL,required_course_id INT NOT NULL,minimum_grade DECIMAL(5,2) DEFAULT 60.00,FOREIGN KEY (course_id) REFERENCES courses(course_id),FOREIGN KEY (required_course_id) REFERENCES courses(course_id)
);-- 10. 为图书馆表添加ISBN唯一约束
ALTER TABLE library ADD CONSTRAINT uc_isbn UNIQUE (isbn);-- 11. 创建学生成绩视图
CREATE VIEW student_course_grades AS
SELECT s.student_id,s.first_name,s.last_name,c.course_name,sc.midterm_score,sc.final_score,sc.total_score
FROM students s
JOIN enrollments e ON s.student_id = e.student_id
JOIN courses c ON e.course_id = c.course_id
JOIN scores sc ON e.enrollment_id = sc.enrollment_id;-- 12. 创建获取学生信息的存储过程
DELIMITER //
CREATE PROCEDURE get_student_info(IN student_id INT)
BEGINSELECT s.student_id,s.first_name,s.last_name,s.email,s.enrollment_date,d.department_name,s.scholarshipFROM students sJOIN departments d ON s.department_id = d.department_idWHERE s.student_id = student_id;
END //
DELIMITER ;-- 13. 创建删除学生前的检查触发器
DELIMITER //
CREATE TRIGGER before_student_delete
BEFORE DELETE ON students
FOR EACH ROW
BEGINDECLARE enrollment_count INT;DECLARE borrow_count INT;-- 检查是否有选课记录SELECT COUNT(*) INTO enrollment_count FROM enrollments WHERE student_id = OLD.student_id;-- 检查是否有借阅记录SELECT COUNT(*) INTO borrow_count FROM borrow_records WHERE student_id = OLD.student_id AND return_date IS NULL;IF enrollment_count > 0 THENSIGNAL SQLSTATE '45000'SET MESSAGE_TEXT = 'Cannot delete student with course enrollments';END IF;IF borrow_count > 0 THENSIGNAL SQLSTATE '45000'SET MESSAGE_TEXT = 'Cannot delete student with borrowed books';END IF;
END //
DELIMITER ;-- 14. 添加成绩检查约束
ALTER TABLE scores 
ADD CONSTRAINT chk_score_range 
CHECK ((midterm_score BETWEEN 0 AND 100 OR midterm_score IS NULL) AND(final_score BETWEEN 0 AND 100 OR final_score IS NULL) AND(assignment_score BETWEEN 0 AND 100 OR assignment_score IS NULL)
);-- 15. 创建临时表存储优秀学生
CREATE TEMPORARY TABLE top_students AS
SELECT s.student_id,s.first_name,s.last_name,AVG(sc.total_score) AS average_score
FROM students s
JOIN enrollments e ON s.student_id = e.student_id
JOIN scores sc ON e.enrollment_id = sc.enrollment_id
GROUP BY s.student_id, s.first_name, s.last_name
HAVING AVG(sc.total_score) >= 90;

DML操作示例

-- 16. 插入学院数据
INSERT INTO faculty (faculty_name, dean_name, established_year) VALUES
('工程学院', '张院长', 2000),
('理学院', '李院长', 1995),
('文学院', '王院长', 1985);-- 17. 插入新学生数据
INSERT INTO students (first_name, last_name, email, enrollment_date, date_of_birth, department_id, scholarship, phone_number) VALUES
('唐', '雨', 'tangyu@email.com', '2023-09-01', '2004-12-03', 1, 2000.00, '13800138000'),
('宋', '阳', 'songyang@email.com', '2023-09-01', '2004-07-21', 2, 1500.00, '13900139000'),
('秦', '雪', 'qinxue@email.com', '2023-09-01', '2004-03-15', 3, 0.00, '13700137000'),
('许', '明', 'xuming@email.com', '2023-09-01', '2004-09-28', 4, 1000.00, '13600136000'),
('何', '静', 'hejing@email.com', '2023-09-01', '2004-11-11', 5, 2500.00, '13500135000');-- 18. 插入新教师数据
INSERT INTO teachers (first_name, last_name, email, hire_date, department_id, title, salary) VALUES
('韩', '教授', 'han@email.com', '2021-06-10', 1, '副教授', 72000.00),
('董', '老师', 'dong@email.com', '2022-02-15', 2, '讲师', 58000.00),
('曹', '教授', 'cao@email.com', '2019-08-20', 3, '教授', 88000.00);-- 19. 插入新课程数据
INSERT INTO courses (course_code, course_name, credits, teacher_id, department_id) VALUES
('CS501', '人工智能', 4, 1, 1),
('MATH401', '数值分析', 3, 10, 2);-- 20. 插入选课记录
INSERT INTO enrollments (student_id, course_id, enrollment_date, semester, academic_year) VALUES
(16, 14, '2023-09-05', 'Fall', 2023),
(17, 15, '2023-09-05', 'Fall', 2023),
(18, 14, '2023-09-06', 'Fall', 2023),
(19, 15, '2023-09-06', 'Fall', 2023),
(20, 14, '2023-09-07', 'Fall', 2023),
(16, 1, '2023-09-07', 'Fall', 2023),
(17, 5, '2023-09-08', 'Fall', 2023),
(18, 8, '2023-09-08', 'Fall', 2023),
(19, 10, '2023-09-09', 'Fall', 2023),
(20, 11, '2023-09-09', 'Fall', 2023);-- 26. 更新教师工资增加10%
UPDATE teachers SET salary = salary * 1.1;-- 27. 更新计算机系学生奖学金
UPDATE students s
JOIN departments d ON s.department_id = d.department_id
SET s.scholarship = s.scholarship + 1000
WHERE d.department_name = '计算机科学';-- 28. 更新数据库系统课程成绩
UPDATE scores sc
JOIN enrollments e ON sc.enrollment_id = e.enrollment_id
JOIN courses c ON e.course_id = c.course_id
SET sc.final_score = LEAST(sc.final_score + 5, 100)
WHERE c.course_name = '数据库系统';-- 29. 更新逾期罚款
UPDATE borrow_records 
SET fine_amount = DATEDIFF(CURDATE(), due_date) * 0.5
WHERE return_date IS NULL AND due_date < CURDATE();-- 36. 删除成绩为0的记录
DELETE FROM scores WHERE total_score = 0;-- 37. 删除没有学生选修的课程
DELETE FROM courses 
WHERE course_id NOT IN (SELECT DISTINCT course_id FROM enrollments);-- 41. 使用事务删除学生及相关记录
START TRANSACTION;-- 首先删除相关记录
DELETE FROM scores WHERE enrollment_id IN (SELECT enrollment_id FROM enrollments WHERE student_id = 15
);
DELETE FROM enrollments WHERE student_id = 15;
DELETE FROM borrow_records WHERE student_id = 15;
DELETE FROM club_members WHERE student_id = 15;
DELETE FROM event_participants WHERE student_id = 15;-- 最后删除学生
DELETE FROM students WHERE student_id = 15;COMMIT;

综合操作示例

-- 46. 创建校友表并转移数据
CREATE TABLE alumni (alumni_id INT PRIMARY KEY AUTO_INCREMENT,first_name VARCHAR(50) NOT NULL,last_name VARCHAR(50) NOT NULL,email VARCHAR(100) UNIQUE,enrollment_date DATE,graduation_date DATE,department_id INT,current_job VARCHAR(100),FOREIGN KEY (department_id) REFERENCES departments(department_id)
);-- 转移已毕业学生数据(假设2022年入学学生已毕业)
INSERT INTO alumni (first_name, last_name, email, enrollment_date, graduation_date, department_id)
SELECT first_name, last_name, email, enrollment_date, '2023-06-30', department_id
FROM students
WHERE enrollment_date < '2023-01-01';-- 47. 使用MERGE语句同步数据(MySQL不支持MERGE,使用INSERT...ON DUPLICATE KEY UPDATE)
INSERT INTO alumni (first_name, last_name, email, enrollment_date, graduation_date, department_id)
SELECT first_name, last_name, email, enrollment_date, '2023-06-30', department_id
FROM students
WHERE enrollment_date < '2023-01-01'
ON DUPLICATE KEY UPDATE first_name = VALUES(first_name),last_name = VALUES(last_name),graduation_date = VALUES(graduation_date),department_id = VALUES(department_id);-- 48. 使用CASE更新奖学金等级
UPDATE students s
JOIN (SELECT s.student_id,CASE WHEN AVG(sc.total_score) >= 90 THEN 'A'WHEN AVG(sc.total_score) >= 80 THEN 'B'ELSE 'C'END AS scholarship_gradeFROM students sJOIN enrollments e ON s.student_id = e.student_idJOIN scores sc ON e.enrollment_id = sc.enrollment_idGROUP BY s.student_id
) grades ON s.student_id = grades.student_id
SET s.scholarship = CASE grades.scholarship_gradeWHEN 'A' THEN 5000WHEN 'B' THEN 3000ELSE 1000END;-- 49. 使用事务处理借书操作
START TRANSACTION;-- 检查书籍是否可用
SELECT available_copies INTO @available FROM library WHERE book_id = 5;IF @available > 0 THEN-- 减少可用副本数UPDATE library SET available_copies = available_copies - 1 WHERE book_id = 5;-- 添加借阅记录INSERT INTO borrow_records (student_id, book_id, borrow_date, due_date)VALUES (1, 5, CURDATE(), DATE_ADD(CURDATE(), INTERVAL 30 DAY));COMMIT;
ELSEROLLBACK;SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Book not available';
END IF;-- 51. 创建计算GPA的函数
DELIMITER //
CREATE FUNCTION calculate_gpa(student_id INT) RETURNS DECIMAL(3,2)
READS SQL DATA
BEGINDECLARE total_points DECIMAL(5,2);DECLARE total_credits INT;DECLARE gpa DECIMAL(3,2);SELECT SUM(CASE WHEN sc.total_score >= 90 THEN 4.0 * c.creditsWHEN sc.total_score >= 80 THEN 3.0 * c.creditsWHEN sc.total_score >= 70 THEN 2.0 * c.creditsWHEN sc.total_score >= 60 THEN 1.0 * c.creditsELSE 0END),SUM(c.credits)INTO total_points, total_creditsFROM students sJOIN enrollments e ON s.student_id = e.student_idJOIN courses c ON e.course_id = c.course_idJOIN scores sc ON e.enrollment_id = sc.enrollment_idWHERE s.student_id = student_id;IF total_credits > 0 THENSET gpa = total_points / total_credits;ELSESET gpa = 0;END IF;RETURN gpa;
END //
DELIMITER ;-- 52. 创建分页查询存储过程
DELIMITER //
CREATE PROCEDURE get_students_paginated(IN page_number INT,IN page_size INT,OUT total_students INT,OUT total_pages INT
)
BEGIN-- 获取总学生数SELECT COUNT(*) INTO total_students FROM students;-- 计算总页数SET total_pages = CEIL(total_students / page_size);-- 分页查询学生SELECT *FROM studentsORDER BY student_idLIMIT page_sizeOFFSET (page_number - 1) * page_size;
END //
DELIMITER ;-- 53. 使用临时表统计成绩分布
CREATE TEMPORARY TABLE grade_distribution AS
SELECT d.department_name,COUNT(*) AS total_students,SUM(CASE WHEN gpa >= 3.5 THEN 1 ELSE 0 END) AS excellent,SUM(CASE WHEN gpa >= 2.5 AND gpa < 3.5 THEN 1 ELSE 0 END) AS good,SUM(CASE WHEN gpa >= 1.5 AND gpa < 2.5 THEN 1 ELSE 0 END) AS average,SUM(CASE WHEN gpa < 1.5 THEN 1 ELSE 0 END) AS poor
FROM (SELECT s.student_id,s.department_id,calculate_gpa(s.student_id) AS gpaFROM students s
) student_gpas
JOIN departments d ON student_gpas.department_id = d.department_id
GROUP BY d.department_name;-- 54. 使用CTE查询选课路径
WITH RECURSIVE course_path AS (-- 基础查询:没有先修课程的课程SELECT course_id,course_name,CAST(course_name AS CHAR(500)) AS pathFROM coursesWHERE prerequisite_id IS NULLUNION ALL-- 递归查询:有先修课程的课程SELECT c.course_id,c.course_name,CONCAT(cp.path, ' -> ', c.course_name)FROM courses cJOIN course_path cp ON c.prerequisite_id = cp.course_id
)
SELECT * FROM course_path;-- 55. 使用窗口函数计算成绩排名
SELECT s.student_id,s.first_name,s.last_name,c.course_name,sc.total_score,RANK() OVER (PARTITION BY c.course_id ORDER BY sc.total_score DESC) AS course_rank,RANK() OVER (PARTITION BY s.department_id ORDER BY sc.total_score DESC) AS department_rank
FROM students s
JOIN enrollments e ON s.student_id = e.student_id
JOIN courses c ON e.course_id = c.course_id
JOIN scores sc ON e.enrollment_id = sc.enrollment_id;

学习建议

  1. 先掌握基本的DDL语句(CREATE, ALTER, DROP)
  2. 熟练使用DML语句(INSERT, UPDATE, DELETE)
  3. 学习事务处理(BEGIN, COMMIT, ROLLBACK)
  4. 掌握约束的使用(主键、外键、唯一、检查约束)
  5. 学习视图、存储过程、函数和触发器的创建与使用
  6. 练习复杂的数据操作和业务逻辑实现
  7. 学习性能优化技巧(索引、查询优化)
  8. 定期备份和恢复数据库

通过这些完整的数据库操作练习,你将全面掌握SQL从基础到高级的所有操作,真正实现从入门到起飞的目标!

http://www.dtcms.com/a/392310.html

相关文章:

  • MyBatis 从入门到进阶:数据库操作全指南
  • spring cloud 同一服务多实例 websocket跨实例无法共享Session 的解决
  • 如何通过pycharm使用AutoDL服务器
  • 【Linux】4G网卡-AT命令
  • 新版本附近停车场推荐系统demo,基于python+flask+协同推荐+空车位识别+yolov人工智能开发,开发语言python,数据库mysql
  • 《UE5_C++多人TPS完整教程》学习笔记55 ——《P56 网络更新频率(Net Update Frequency)》
  • 华为鸿蒙 ArkTS 实战:基于 RelationalStore 的 SQLite 实现本地数据持久化
  • 流行的 3D 文件格式及其用途指南
  • 腾讯发布一站式工作平台“混元3D Studio
  • TGRS2025 | 视觉语言模型 | 文本驱动自适应网络实现高光谱跨场景零样本分类
  • PyQt6之选项卡示例
  • 研学小程序前端平台开发项目需求规格说明书
  • 【Linux】netplan配置网络;ntp搭建时间服务器;shc将脚本转二进制;ty0tty创建虚拟串口
  • C# ADO.NET 操作学习记录
  • PIT 定时器寄存器配置
  • 算法代码讲座6:最小二乘法理论原理、典型案例与MATLAB实现
  • 【深入浅出】交叉熵损失函数——原理、公式与代码示例
  • Vue实现路由守卫
  • Coze源码分析-资源库-删除工作流-前端源码-核心接口
  • 安踏集团 X OB Cloud:新零售创新如何有“底”和有“数”
  • Web3艺术品交易应用方案
  • Spring 事务管理详解:保障数据一致性的实践指南
  • 软考中级-软件设计师 答题解题思路
  • Java IDEA学习之路:第二周课程笔记归纳
  • SQL语句一文通
  • Ubuntu22.04 双显卡系统使用集显 DRM 渲染的完整流程记录
  • Coze源码分析-资源库-删除工作流-后端源码-IDL/API/应用/领域
  • MySQL库和表的操作语句
  • python、类
  • NumPy高级技巧:向量化、广播与einsum的高效使用