数据表关系图
数据表
CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`sex` enum('female','male') NOT NULL,
`birth` date NOT NULL,
`credit` float(5,2) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=utf8;
CREATE TABLE `teacher` (
`id` int(11) NOT NULL,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `course` (
`id` int(11) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`tid` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `score` (
`sid` int(11) NOT NULL,
`cid` int(11) NOT NULL,
`score` float(5,2) DEFAULT NULL,
PRIMARY KEY (`sid`,`cid`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
添加学生表数据
存储过程,添加 学生表(student
)
DELETE FROM student;
ALTER TABLE student AUTO_INCREMENT = 1;
DROP TABLE IF EXISTS temp_stu;
CREATE TEMPORARY TABLE temp_stu(
name VARCHAR(255)
);
INSERT INTO `temp_stu` (`name`) VALUES ('张三'),('李四'),('王五'),('赵六'),('牛金霞'),('闫景立'),('孙浩'),('周莉'),('吴鹏'),('郑洁'),('陈婷婷'),('刘洋'),('高敏'),('黄磊'),('林静'),('郭涛'),('何婉如'),('梁志远'),('罗芳芳'),('谢霆锋'),('唐嫣'),('韩雪'),('冯小刚'),('程思远');
DROP PROCEDURE IF EXISTS insert_student_records;
DELIMITER //
CREATE PROCEDURE insert_student_records()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE student_name VARCHAR(255);
DECLARE student_sex ENUM('female', 'male');
DECLARE random_year INT;
DECLARE random_month INT;
DECLARE random_day INT;
DECLARE days_in_month INT;
DECLARE credit FLOAT(5,2);
-- 声明游标
DECLARE nameset CURSOR FOR SELECT name FROM temp_stu;
-- 声明继续处理程序
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN nameset;
read_loop: LOOP
FETCH nameset INTO student_name;
IF done THEN
LEAVE read_loop;
END IF;
SET student_sex = IF(RAND() < 0.5, 'female', 'male');
-- 随机选择一个年份(1994, 1995, 1997, 1998, 1999)
SET random_year = FLOOR(1 + RAND() * 5) + 1993;
IF random_year = 1996 THEN
SET random_year = CASE FLOOR(RAND() * 4) + 1994 WHEN 1996 THEN 1994 + FLOOR(RAND() * 4) ELSE random_year - 1 END;
END IF;
SET random_month = FLOOR(1 + RAND() * 12);
-- 计算该月的天数(考虑闰年)
SET days_in_month = CASE
WHEN (random_month = 2 AND (random_year % 4 = 0 AND (random_year % 100 != 0 OR random_year % 400 = 0))) THEN 29
WHEN random_month IN (4, 6, 9, 11) THEN 30
ELSE 31
END;
SET random_day = FLOOR(1 + RAND() * days_in_month);
SET @birth_date = CONCAT(random_year, '-', LPAD(random_month, 2, '0'), '-', LPAD(random_day, 2, '0'));
SET credit = CASE
WHEN RAND() < 0.1 THEN 50 - 30 * RAND()
WHEN RAND() < 0.7 THEN 50 + 30 * RAND()
ELSE 80 + 20 * RAND()
END;
-- 插入到student表
INSERT INTO student(name, sex, birth, credit) VALUES(student_name, student_sex, @birth_date, ROUND(credit, 2));
END LOOP;
CLOSE nameset;
END //
DELIMITER ;
-- SHOW CREATE PROCEDURE insert_student_records;
CALL insert_student_records();
DROP PROCEDURE IF EXISTS insert_student_records;
SELECT * FROM student;
其他表
-- 清理环境
DELETE FROM course;
DELETE FROM teacher;
DELETE FROM score;
DROP PROCEDURE IF EXISTS insert_course_records;
DROP PROCEDURE IF EXISTS insert_teacher_records;
DROP PROCEDURE IF EXISTS insert_score_records;
DROP TABLE IF EXISTS temp_course;
CREATE TEMPORARY TABLE temp_course (
value VARCHAR(255)
);
-- 插入数据到临时表
INSERT INTO temp_course (value) VALUES ('语文'), ('数学'), ('英语'), ('政治'), ('地理'), ('历史'), ('物理'), ('化学'), ('生物'), ('C++'), ('Python'), ('机器学习'), ('强化学习'), ('自然语言处理'), ('关联规则挖掘');
DROP TABLE IF EXISTS temp_teacher;
CREATE TEMPORARY TABLE temp_teacher (
value VARCHAR(255)
);
-- 插入数据到临时表
INSERT INTO temp_teacher (value) VALUES ('李明'), ('王芳'), ('张伟'), ('赵敏'), ('刘洋'), ('陈静'), ('周杰'), ('孙磊'),('徐丽'), ('朱强'), ('邓敏'), ('韩雪');
DELIMITER //
CREATE PROCEDURE insert_course_records()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE course_id INT DEFAULT 1;
DECLARE course_name VARCHAR(255);
DECLARE course_num INT DEFAULT 15;
DECLARE teacher_num INT DEFAULT 12;
-- 声明游标
DECLARE courseset CURSOR FOR SELECT value FROM temp_course;
-- 声明继续处理程序
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN courseset;
read_loop: LOOP
FETCH courseset INTO course_name;
IF done THEN
LEAVE read_loop;
END IF;
SET @teacher_id = CEILING(teacher_num * RAND());
INSERT INTO course(id, name, tid) VALUES(course_id, course_name, @teacher_id);
SET course_id = course_id +1;
END LOOP read_loop;
CLOSE courseset;
END //
CREATE PROCEDURE insert_teacher_records()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE teacher_id INT DEFAULT 1;
DECLARE teacher_name VARCHAR(255);
DECLARE teacherset CURSOR FOR SELECT value FROM temp_teacher;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN teacherset;
read_loop: LOOP
FETCH teacherset INTO teacher_name;
IF done THEN
LEAVE read_loop;
END IF;
INSERT INTO teacher(id, name) VALUES(teacher_id, teacher_name);
SET teacher_id = teacher_id + 1;
END LOOP read_loop;
CLOSE teacherset;
END //
CREATE PROCEDURE insert_score_records()
BEGIN
DECLARE student_num INT DEFAULT 24;
DECLARE course_num INT DEFAULT 15;
DECLARE student_id INT DEFAULT 1;
DECLARE course_id INT DEFAULT 1;
DECLARE score FLOAT(5,2);
WHILE student_id <= student_num DO
SET @temp_course_num = FLOOR(course_num / 3 * RAND());
SET @course_idx = 1;
WHILE @course_idx <= @temp_course_num DO
SET course_id = CASE
WHEN RAND() < 0.4 THEN @course_idx
WHEN RAND() < 0.5 THEN FLOOR(course_num / 3) + @course_idx
ELSE FLOOR(course_num / 3 * 2) + @course_idx
END ;
SET score = CASE
WHEN RAND() < 0.3 THEN ROUND(50 - 20 * RAND(), 2)
WHEN RAND() < 0.8 THEN ROUND(50 + 30 * RAND(), 2)
ELSE ROUND(80 + 20 * RAND(), 2)
END ;
INSERT INTO score(sid,cid, score) VALUES(student_id, course_id, score);
SET @course_idx = @course_idx + 1;
END WHILE;
SET student_id = student_id + 1;
END WHILE;
END//
DELIMITER ;
CALL insert_course_records();
CALL insert_teacher_records();
CALL insert_score_records();
DROP PROCEDURE IF EXISTS insert_course_records;
DROP PROCEDURE IF EXISTS insert_teacher_records;
DROP PROCEDURE IF EXISTS insert_score_records;
SELECT * from course;
SELECT * from teacher;
SELECT * FROM score;
查询示例
- 查询
语文
成绩比数学
成绩高的学生
SELECT id, name, a.score '语文' , b.score '数学' FROM student
JOIN (SELECT sid, score FROM score WHERE cid = 1) a on id = a.sid
JOIN (SELECT sid, score FROM score WHERE cid = 2) b on id = b.sid
WHERE a.score > b.score;
结果
+----+-----------+--------+--------+
| id | name | 语文 | 数学 |
+----+-----------+--------+--------+
| 8 | 周莉 | 82.34 | 75.57 |
| 9 | 吴鹏 | 87.00 | 42.97 |
| 10 | 郑洁 | 99.90 | 77.36 |
| 17 | 何婉如 | 58.68 | 51.54 |
| 24 | 程思远 | 82.41 | 65.65 |
+----+-----------+--------+--------+
5 rows in set (0.00 sec)