diff --git a/2207/天天乐学答案/MySQL练习(一).md b/2207/天天乐学答案/MySQL练习(一).md new file mode 100644 index 0000000..acbec3b --- /dev/null +++ b/2207/天天乐学答案/MySQL练习(一).md @@ -0,0 +1,344 @@ +### 第一套 + +```sql +#1 插入记录 +/* +主键自增字段:DEFAULT +设置成空值:NULL +*/ +INSERT INTO t_employee() +VALUES('e0013', '刘红', '女', 22, '实习生', 'd0002', NULL); +#2.修改表结构 +/* +修改表中字段的数据类型 +ALTER TABLE 表名 MODIFY 字段名 数据类型 [约束]; +*/ +ALTER TABLE t_employee MODIFY sex ENUM('男', '女'); +#3 创建外键 +/* +学生表(学号、姓名、班级编号) +班级表(班级编号、班级名称) +外键表:学生表 主键表:班级表 +ALTER TABLE 学生表 ADD CONSTRAINT fk_st FOREIGN KEY(班级编号) REFERENCES 班级表(班级编号); + +FOREIGN KEY(字段) 外键表中的字段 +REFERENCES 表名(字段) 字段是表中的主键 +*/ +ALTER TABLE 表名 ADD CONSTRAINT 外键名 FOREIGN KEY(字段名) REFERENCES 表名(主键字段名); +ALTER TABLE t_employee ADD CONSTRAINT fK_did FOREIGN KEY(did) REFERENCES t_department(did); + +#4 排序、分页查询 tj11 +/* +基础查询 +SELECT 字段 +FROM 表 +ORDER BY 需要排序的字段 ASC/DESC(升序/降序) +LIMIT 起始位置,个数; +*/ +#查询出员工的所有信息 +SELECT * +FROM t_employee; +#在基础查询之上对年龄进行降序排序 +SELECT * +FROM t_employee +ORDER BY age DESC; +#在排序的基础之上,进行分页 +SELECT * +FROM t_employee +ORDER BY age DESC +LIMIT 5, 8;#第0个代表第一个 第六个使用的位置是5 + +#5条件查询 tj12 +/* +SELECT 字段 +FROM 表 +WHERE 条件; +*/ +SELECT * +FROM t_salary +WHERE money >= 5000 AND money <= 8000; + +#6 tj13 分组查询 +SELECT eid, MAX(money) +FROM t_salary +GROUP BY eid; + +#7 tj14 多表联查+条件过滤 +SELECT d.dname, e.ename +FROM t_employee e, t_department d +WHERE e.did = d.did AND e.position = '经理'; + +#8 +CREATE VIEW v_hrm AS +SELECT d.dname, e.ename, s.money, s.stime +FROM t_employee e, t_department d, t_salary s +WHERE e.did = d.did AND e.eid = s.eid +ORDER BY s.stime DESC; + +#9 触发器 +DELIMITER $$ +DROP TRIGGER IF EXISTS tri_updateGroup; +CREATE TRIGGER tri_updateGroup +BEFORE UPDATE ON t_employee +FOR EACH ROW +BEGIN + IF NEW.age != OLD.age THEN + IF NEW.age<30 THEN + SET NEW.groups = '青年'; + ELSEIF NEW.age<50 THEN + SET NEW.groups = '中年'; + ELSE + SET NEW.groups = '老年'; + END IF; + END IF; +END $$ +DELIMITER ; + +#10 存储过程 +DELIMITER $$ #改变代码结束符 +DROP PROCEDURE IF EXISTS pro_GetTopSalary;#创建存储过程之前先删除 +#设置存储过程名,传入传出参数名和数据类型 +CREATE PROCEDURE pro_GetTopSalary(IN in_did CHAR(10), OUT out_ename VARCHAR(30)) +BEGIN + #连接查询+排序+分页 + SELECT e.ename INTO out_ename + FROM t_employee e, t_salary s + WHERE e.eid = s.eid AND e.did = in_did + ORDER BY s.money DESC + LIMIT 1; +END $$ +DELIMITER ; +#调用存储过程 传入用户变量接收传出数据并使用打印出来 +CALL pro_GetTopSalary('d0001', @result); +SELECT @result; +``` + +### 第二套 + +```sql +#1 创建表 +CREATE TABLE t_booking( + bid CHAR(10) PRIMARY KEY, + rid CHAR(10) NOT NULL, + customerName VARCHAR(50), + tel VARCHAR(30), + btime DATE +); + +#2 插入记录 +INSERT INTO t_booking() +VALUES('b0001', 'r0002', '诸葛亮', '1821234567', '2023-10-01'); + +#3 添加字段 +ALTER TABLE t_hotel ADD introduce VARCHAR(255); + +#4 更新记录 +UPDATE t_room r +SET r.price = 500 +WHERE r.rid = 'r0003'; + +#5 tj11 +SELECT * +FROM t_hotel h +WHERE h.`level` IN ('二星', '三星'); + +#6 tj12 +SELECT h.hid, ROUND(AVG(r.price), 2) +FROM t_hotel h, t_room r +WHERE h.hid = r.hid +GROUP BY h.hid; + +#7 子查询 + 视图 +CREATE VIEW v_hotel AS +SELECT h.hname, r.rname, r.price +FROM t_hotel h, t_room r +WHERE h.hid = r.hid AND r.price =( + SELECT MAX(price) + FROM t_room + WHERE hid = h.hid +); + +#8 触发器 +DELIMITER $$ +DROP TRIGGER IF EXISTS tri_updateIntroduce; +CREATE TRIGGER tri_updateIntroduce +BEFORE UPDATE ON t_hotel +FOR EACH ROW +BEGIN + IF NEW.`level` = '一星' OR NEW.`level` = '二星' THEN + SET NEW.introduce = '实用'; + ELSEIF NEW.`level` = '三星' OR NEW.`level` = '四星' THEN + SET NEW.introduce = '豪华'; + ELSEIF NEW.`level` = '五星' THEN + SET NEW.introduce = '奢华'; + END IF; +END $$ +DELIMITER ; + +#9 存储过程 +DELIMITER $$ +DROP PROCEDURE IF EXISTS pro_GetLowPrice; +CREATE PROCEDURE pro_GetLowPrice(IN in_rname VARCHAR(30), OUT out_hname VARCHAR(30)) +BEGIN + SELECT h.hname INTO out_hname + FROM t_hotel h, t_room r + WHERE h.hid = r.hid AND r.rname = in_rname + ORDER BY r.price + LIMIT 1; +END $$ +DELIMITER ; + +CALL pro_GetLowPrice('标准间', @result); +SELECT @result; +``` + +### 第三套 + +```sql +#1 +CREATE TABLE tb_order( + oid INT PRIMARY KEY AUTO_INCREMENT COMMENT '订单ID', + odate DATETIME NOT NULL COMMENT '下单日期', + quantity INT NOT NULL DEFAULT 1 COMMENT '下单数量' +); + +#2 +ALTER TABLE tb_books MODIFY price DECIMAL(10, 2); + +#3 +ALTER TABLE tb_book_authors ADD CONSTRAINT tB_ibfk_1 FOREIGN KEY(book_id) REFERENCES tb_books(book_id); + +ALTER TABLE tb_book_authors ADD CONSTRAINT tB_ibfk_2 FOREIGN KEY(author_id) REFERENCES tb_authors(author_id); + +#4 +ALTER TABLE tb_authors ADD avatar MEDIUMBLOB; + +#5 +#使用查询和LOAD_FILE函数 导入指定路径的图片 +SELECT LOAD_FILE('C:/TTLXExam/20501071168/MYSQLDB/3/jinyong.jpg'); + +UPDATE tb_authors a +SET a.avatar = LOAD_FILE('C:/TTLXExam/20501071168/MYSQLDB/3/jinyong.jpg') +WHERE a.author_name = '金庸'; + +#6 +#INSTR(主串, 子串) 判断子串在主串中的位置并返回 +#SUBSTR(字符串, 起始位置) 从起始位置开始截取字符串 +SELECT SUBSTR(b.note,INSTR(b.note,'-')+2) +FROM tb_books b; + +UPDATE tb_books b +SET b.note = SUBSTR(b.note,INSTR(b.note,'-')+2); + +#7 tj11 多表连接+条件+排序 +SELECT b.book_id, b.title, a.author_id, a.author_name, b.publication_date +FROM tb_books b, tb_authors a +WHERE b.note = a.author_name AND YEAR(b.publication_date) BETWEEN 1980 AND 2010 +ORDER BY b.publication_date DESC; + +#8 tj12 多表连接+分组+分组后条件 +SELECT a.author_id, a.author_name, COUNT(*) +FROM tb_books b, tb_authors a +WHERE b.note = a.author_name +GROUP BY a.author_id +HAVING COUNT(*) > 1; + +#9 视图 +CREATE VIEW v_book AS +SELECT b.genre, a.author_name, COUNT(*) c +FROM tb_books b, tb_authors a +WHERE b.note = a.author_name +GROUP BY b.genre, a.author_id #按照图书类别和作者名称进行分组 +HAVING COUNT(*) = ( #子查询用来统计这个类别中 数量最多的作者的图书数量 + SELECT COUNT(*) + FROM tb_books + WHERE b.genre = genre + GROUP BY note + ORDER BY COUNT(*) DESC + LIMIT 1 +); + +#10 触发器 +DELIMITER $$ +DROP TRIGGER IF EXISTS tri_updateCentury; +CREATE TRIGGER tri_updateCentury +BEFORE UPDATE ON tb_books +FOR EACH ROW +BEGIN + #方式一 + /* + 计算出世纪数+字符串拼接 + IF NEW.publication_date <> OLD.publication_date THEN + SET NEW.century = CONCAT(FLOOR(YEAR(NEW.publication_date)/100) + 1, '世纪'); + END IF; + */ + #方式二 使用多分支IF + IF NEW.publication_date <> OLD.publication_date THEN + IF YEAR(NEW.publication_date) BETWEEN 1800 AND 1899 THEN + SET NEW.century = '19世纪'; + ELSEIF YEAR(NEW.publication_date) BETWEEN 1900 AND 1999 THEN + SET NEW.century = '20世纪'; + ELSEIF YEAR(NEW.publication_date) BETWEEN 2000 AND 2099 THEN + SET NEW.century = '21世纪'; + END IF; + END IF; +END $$ +DELIMITER ; + +SELECT CONCAT(FLOOR(YEAR(publication_date)/100) + 1, '世纪') +FROM tb_books; + +#11 存储过程 +DELIMITER $$ +DROP PROCEDURE IF EXISTS pro_GetTopFictionPrice; +CREATE PROCEDURE pro_GetTopFictionPrice(IN in_genre VARCHAR(255), OUT out_title VARCHAR(255)) +BEGIN + SELECT b.title INTO out_title + FROM tb_books b + WHERE b.genre = in_genre AND YEAR(b.publication_date) BETWEEN 2000 AND 2099 + ORDER BY b.price DESC + LIMIT 1; +END $$ +DELIMITER ; +``` + +### 第四套 + +```sql +#1 +ALTER TABLE tb_students MODIFY gender ENUM('男', '女', '未知'); +#2 +ALTER TABLE tb_scores MODIFY score FLOAT(7, 2); +#3 +CREATE TABLE tb_scores_bak1 AS +SELECT * +FROM tb_scores; +#4 +UPDATE test1 t1, ( + SELECT tname, CONCAT(tname,'@',COUNT(*)) str + FROM test1 + GROUP BY tname + HAVING COUNT(*) IN (3, 4) +)t2 +SET t1.tname = t2.str +WHERE t1.tname = t2.tname; + +#5 +SELECT * +FROM tb_courses c +ORDER BY c.cid+0 +LIMIT 4, 11; + +#6 +SELECT s.stuname, TIMESTAMPDIFF(YEAR,s.birthday,'2023-12-01') +FROM tb_students s +WHERE TIMESTAMPDIFF(YEAR,s.birthday,'2023-12-01') BETWEEN 30 AND 40; + +#7 + + +#8 + + +``` +