MySQL查询作业(未完成)

本文详细探讨了MySQL查询优化的重要性,从索引使用、JOIN操作优化、子查询转换以及查询语句重构等方面,提供了实用的优化策略。通过实例分析,揭示了如何有效提升数据库查询性能,降低系统负载。
CREATE TABLE Student(
	s_id VARCHAR(20),
	s_name VARCHAR(20) NOT NULL DEFAULT '',
	s_birth VARCHAR(20) NOT NULL DEFAULT '',
	s_sex VARCHAR(10) NOT NULL DEFAULT '',
	PRIMARY KEY(s_id)
);
CREATE TABLE Course(
	c_id  VARCHAR(20),
	c_name VARCHAR(20) NOT NULL DEFAULT '',
	t_id VARCHAR(20) NOT NULL,
	PRIMARY KEY(c_id)
);
CREATE TABLE Teacher(
	t_id VARCHAR(20),
	t_name VARCHAR(20) NOT NULL DEFAULT '',
	PRIMARY KEY(t_id)
);
CREATE TABLE Score(
	s_id VARCHAR(20),
	c_id  VARCHAR(20),
	s_score INT(3),
	PRIMARY KEY(s_id,c_id)
);
INSERT INTO Student VALUES('01' , '赵雷' , '1990-01-01' , '男');
INSERT INTO Student VALUES('02' , '钱电' , '1990-12-21' , '男');
INSERT INTO Student VALUES('03' , '孙风' , '1990-05-20' , '男');
INSERT INTO Student VALUES('04' , '李云' , '1990-08-06' , '男');
INSERT INTO Student 
# 题目重述 根据提供的《数据库系统课程设计项目任务书.docx》内容,需完成一个基于 MySQL 的完整数据库项目作业,具体包括: 1. **数据库与表的设计与创建**:在 `teachingdb` 数据库中创建 `student`、`course`、`teach` 和 `score` 四张表,并设置主键、外键及约束。 2. **数据插入**:将指定数据插入四张表中。 3. **基础 SQL 操作**:执行字段增删改、数据增删改查、条件查询、聚合统计、连接查询、子查询等共计 31 项操作。 4. **高级数据库编程**:实现存储过程、函数、触发器共 5 项,用于模糊查询、学分统计、自动更新总学分、级联删除等功能。 --- # 详解 ## 一、数据库与表的创建 ```sql -- 创建数据库 CREATE DATABASE IF NOT EXISTS teachingdb CHARACTER SET utf8mb4; USE teachingdb; -- 创建学生表 student CREATE TABLE student ( sno CHAR(5) PRIMARY KEY, sname VARCHAR(20) NOT NULL, sdept VARCHAR(20) NOT NULL, sclass CHAR(2) NOT NULL, ssex CHAR(2), sbirth DATE, total_credit INT DEFAULT 0 ); -- 创建课程表 course CREATE TABLE course ( cno CHAR(3) PRIMARY KEY, cname VARCHAR(50) NOT NULL, credit_hour INT, credit DECIMAL(3,1) ); -- 创建教师表 teach CREATE TABLE teach ( tno CHAR(6) PRIMARY KEY, tname VARCHAR(20) NOT NULL, tsex CHAR(2), tdept VARCHAR(20) ); -- 创建成绩表 score CREATE TABLE score ( sno CHAR(5), cno CHAR(3), tno CHAR(6), grade DECIMAL(4,1), PRIMARY KEY (sno, cno, tno), FOREIGN KEY (sno) REFERENCES student(sno), FOREIGN KEY (cno) REFERENCES course(cno), FOREIGN KEY (tno) REFERENCES teach(tno) ); ``` --- ## 二、数据插入 ```sql -- 插入学生数据 INSERT INTO student VALUES ('96001','马小燕','计算机','01','女','2000-01-02',0), ('96002','黎明','计算机','01','男','2000-03-05',0), ('96003','刘东明','数学','01','男','2000-10-05',0), ('96004','赵志勇','信息','02','男','2000-08-08',0), ('97001','马蓉','数学','02','女','2001-03-04',0), ('97002','李成功','计算机','01','男','2001-09-10',0), ('97003','黎明','信息','03','女','2002-02-08',0), ('97004','李丽','计算机','02','女','2002-01-05',0), ('96005','司马志明','计算机','02','男','2001-11-23',0); -- 插入课程数据 INSERT INTO course VALUES ('001','数学分析',64,4), ('002','普通物理',64,4), ('003','微机原理',56,3.5), ('004','数据结构',64,4), ('005','操作系统',56,3.5), ('006','数据库原理',56,3.5), ('007','编译原理',48,3), ('008','程序设计',32,2); -- 插入教师数据 INSERT INTO teach VALUES ('052501','王成刚','男','计算机'), ('052502','李正科','男','计算机'), ('052503','严敏','女','数学'), ('052504','赵高','男','数学'), ('052505','刘玉兰','女','计算机'), ('052506','王成刚','男','信息'), ('052507','马悦','女','计算机'); -- 插入成绩数据 INSERT INTO score VALUES ('96001','001','052503',77.5),('96001','003','052501',89),('96001','004','052502',86), ('96001','005','052505',82),('96002','001','052504',88),('96002','003','052502',92.5), ('96002','006','052507',90),('96005','004','052502',92),('96005','005','052505',90), ('96005','006','052505',89),('96005','007','052507',78),('96003','001','052504',69), ('97001','001','052504',96),('97001','008','052505',95),('96004','001','052503',87), ('96003','003','052501',91),('97002','003','052502',91),('97002','004','052505',NULL), ('97002','006','052507',92),('97004','005','052502',90),('97004','006','052501',85); ``` --- ## 三、基础 SQL 功能实现 ```sql -- 1. 增加籍贯字段 ALTER TABLE student ADD nativeplace VARCHAR(20); -- 2. 删除籍贯字段 ALTER TABLE student DROP COLUMN nativeplace; -- 3. 修改 ssex 字段类型 ALTER TABLE student MODIFY ssex VARCHAR(3); -- 4. 在 course.cname 上添加唯一约束 ALTER TABLE course ADD CONSTRAINT uk_cno UNIQUE(cname); -- 5. 插入新学生 INSERT INTO student VALUES('11111','马明','计算机','01','女','2000-01-02',NULL); -- 6. 所有学生总学分加 2(含 NULL) UPDATE student SET total_credit = IFNULL(total_credit, 0) + 2; -- 7. 修改马小燕出生日期 UPDATE student SET sbirth = '2000-01-22' WHERE sname = '马小燕'; -- 8. 删除学号为 '11111' 的学生 DELETE FROM student WHERE sno = '11111'; -- 9. 创建表 s1,结构内容相同 CREATE TABLE s1 AS SELECT * FROM student; -- 10. 删除 s1 中计算机系学生 DELETE FROM s1 WHERE sdept = '计算机'; -- 11. 删除 s1 表 DROP TABLE s1; -- 12. 2000 年出生的学生(中文列名) SELECT sno AS 学号, sname AS 姓名 FROM student WHERE YEAR(sbirth) = 2000; -- 13. 选修课程的学生学号(去重) SELECT DISTINCT sno FROM score; -- 14. 学时在 1-50 之间的课程 SELECT * FROM course WHERE credit_hour BETWEEN 1 AND 50; -- 15. 不是计算机系或信息系的学生 SELECT * FROM student WHERE sdept NOT IN ('计算机', '信息'); -- 16. 姓名至少三字且倒数第三字为“马” SELECT sname FROM student WHERE CHAR_LENGTH(sname) >= 3 AND SUBSTR(sname, -3, 1) = '马'; -- 17. 选修 052501 教师,成绩 80~90,学号 96xxx SELECT * FROM score WHERE tno = '052501' AND grade BETWEEN 80 AND 90 AND sno LIKE '96%'; -- 18. 没有成绩的学生(成绩为 NULL) SELECT sno, cno FROM score WHERE grade IS NULL; -- 19. 学生总人数 SELECT COUNT(*) AS 学生总数 FROM student; -- 20. 选修课程的学生人数 SELECT COUNT(DISTINCT sno) AS 选修人数 FROM score; -- 21. 各门课程的最高、最低、平均成绩 SELECT cno, MAX(grade), MIN(grade), AVG(grade) FROM score GROUP BY cno; -- 22. 学生人数不足 3 人的系 SELECT sdept, COUNT(*) AS cnt FROM student GROUP BY sdept HAVING cnt < 3; -- 23. 计算机系各班人数,倒序排列 SELECT sclass, COUNT(*) AS cnt FROM student WHERE sdept = '计算机' GROUP BY sclass ORDER BY cnt DESC; -- 24. 自然连接:选修严敏老师“数学分析”课程的学生 SELECT s.sname, c.cname, t.tname, sc.grade FROM student s, course c, teach t, score sc WHERE s.sno = sc.sno AND c.cno = sc.cno AND t.tno = sc.tno AND t.tname = '严敏' AND c.cname = '数学分析'; -- 25. 等值连接:选修“数学分析”的学生姓名、课程名、成绩 SELECT s.sname, c.cname, sc.grade FROM student s JOIN score sc ON s.sno = sc.sno JOIN course c ON sc.cno = c.cno WHERE c.cname = '数学分析'; -- 26. JOIN 连接:选修课程的学生学号姓名 SELECT DISTINCT s.sno, s.sname FROM student s JOIN score sc ON s.sno = sc.sno; -- 27. 自身连接:年龄大于‘刘东明’的学生 SELECT s1.sname, s1.sbirth FROM student s1, student s2 WHERE s2.sname = '刘东明' AND s1.sbirth < s2.sbirth; -- 28. 外部连接:未选修课程的学生 SELECT s.sno, s.sname FROM student s LEFT JOIN score sc ON s.sno = sc.sno WHERE sc.sno IS NULL; -- 29. 不相关子查询:年龄大于‘刘东明’ SELECT sname, sbirth FROM student WHERE sbirth < (SELECT sbirth FROM student WHERE sname = '刘东明'); -- 30. 未选修任何课程的学生(同28) -- 已实现 -- 31. 比数学系所有学生年龄都大的学生 SELECT sname, sdept FROM student WHERE sbirth < ALL(SELECT sbirth FROM student WHERE sdept = '数学'); -- 32. 选修了 004 课程的学生姓名和系 SELECT s.sname, s.sdept FROM student s JOIN score sc ON s.sno = sc.sno WHERE sc.cno = '004'; -- 33. 选修了“刘东明”所选全部课程的学生学号 SELECT s.sno FROM student s WHERE NOT EXISTS ( SELECT cno FROM score WHERE sno = '96003' EXCEPT SELECT cno FROM score WHERE sno = s.sno ); -- 34. 选修了全部课程的学生学号 SELECT sno FROM score GROUP BY sno HAVING COUNT(DISTINCT cno) = (SELECT COUNT(*) FROM course); ``` --- ## 四、高级编程:存储过程、函数、触发器 ### 1. 模糊查找存储过程 ```sql DELIMITER // CREATE PROCEDURE pro_findname(IN keyword CHAR(1)) BEGIN SELECT * FROM student WHERE sname LIKE CONCAT('%', keyword, '%'); END // DELIMITER ; ``` ### 2. 计算总学分函数 ```sql DELIMITER // CREATE FUNCTION count_credit(sno_input CHAR(5)) RETURNS INT READS SQL DATA BEGIN DECLARE total INT DEFAULT 0; SELECT SUM(c.credit) INTO total FROM score sc JOIN course c ON sc.cno = c.cno WHERE sc.sno = sno_input AND sc.grade >= 60; RETURN IFNULL(total, 0); END // DELIMITER ; ``` ### 3. 调用函数更新总学分的存储过程 ```sql DELIMITER // CREATE PROCEDURE p_count_credit() BEGIN DECLARE done INT DEFAULT FALSE; DECLARE s_no CHAR(5); DECLARE cur CURSOR FOR SELECT sno FROM student; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; OPEN cur; read_loop: LOOP FETCH cur INTO s_no; IF done THEN LEAVE read_loop; END IF; UPDATE student SET total_credit = count_credit(s_no) WHERE sno = s_no; END LOOP; CLOSE cur; END // DELIMITER ; ``` ### 4. 触发器:自动更新总学分(插入成绩时) ```sql DELIMITER // CREATE TRIGGER sum_credit AFTER INSERT ON score FOR EACH ROW BEGIN UPDATE student SET total_credit = total_credit + ( SELECT credit FROM course WHERE cno = NEW.cno ) WHERE sno = NEW.sno AND NEW.grade >= 60; END // DELIMITER ; ``` ### 5. 级联删除触发器 ```sql DELIMITER // CREATE TRIGGER del_student_score AFTER DELETE ON student FOR EACH ROW BEGIN DELETE FROM score WHERE sno = OLD.sno; END // DELIMITER ; ``` --- # 知识点 - **SQL DDL 与 DML**:掌握 `CREATE`, `ALTER`, `DROP`, `INSERT`, `UPDATE`, `DELETE` 等语句,用于数据库结构与数据操作。 - **多表连接与子查询**:理解 `JOIN`、`LEFT JOIN`、`EXISTS`、`NOT EXISTS`、`ALL` 等用于复杂查询的技术。 - **数据库编程对象**:掌握存储过程、函数、触发器的定义与使用,实现业务逻辑自动化与数据一致性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值