数据库mysql篇典型的一些练习题目
Posted Tanglaoer
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据库mysql篇典型的一些练习题目相关的知识,希望对你有一定的参考价值。
班级表 class
学生表student
老师表 teacher
课程表course
成绩表 score
准备数据
创建数据库
create database tang_test charset=\'utf8\';
创建表
CREATE TABLE class ( cid INT NOT NULL AUTO_INCREMENT PRIMARY KEY, caption VARCHAR(20) ) DEFAULT CHARSET = \'utf8\'; CREATE TABLE student ( sid INT NOT NULL AUTO_INCREMENT PRIMARY KEY, sname VARCHAR(20), gender VARCHAR(20), class_id INT, CONSTRAINT fk_clsid FOREIGN KEY (class_id) REFERENCES class (cid) ) DEFAULT CHARSET = \'utf8\'; CREATE TABLE teacher ( tid INT NOT NULL AUTO_INCREMENT PRIMARY KEY, tname VARCHAR(32) ) DEFAULT CHARSET = \'utf8\'; CREATE TABLE course ( cid INT NOT NULL AUTO_INCREMENT PRIMARY KEY, cname VARCHAR(20), tearch_id INT, CONSTRAINT fk_tea FOREIGN KEY (tearch_id) REFERENCES teacher (tid) ) DEFAULT CHARSET = \'utf8\'; CREATE TABLE score ( sid INT NOT NULL AUTO_INCREMENT PRIMARY KEY, student_id INT, corse_id INT, number INT, CONSTRAINT fk_sco_stu FOREIGN KEY (student_id) REFERENCES student (sid), CONSTRAINT fk_sco_cor FOREIGN KEY (corse_id) REFERENCES course (cid) ) DEFAULT CHARSET = \'utf8\';
添加联合唯一约束
ALTER TABLE score ADD UNIQUE i_stu_cor(student_id, corse_id);
题目与答案
# 查询“生物”课程比“物理”课程成绩高的所有学生的学号; SELECT tb1.student_id FROM (SELECT student_id, number FROM score s LEFT JOIN course c ON s.corse_id = c.cid WHERE c.cname = \'体育\') AS tb1 LEFT JOIN ( SELECT student_id, number FROM score s LEFT JOIN course c ON s.corse_id = c.cid WHERE c.cname = \'物理\') AS tb2 ON tb1.student_id = tb2.student_id WHERE tb1.number > tb2.number; # 查询平均成绩大于60分的同学的学号和平均成绩; SELECT s.sid, avg(number) FROM score LEFT JOIN student s ON score.student_id = s.sid GROUP BY s.sid HAVING avg(number) > 60; # 查询所有同学的学号、姓名、选课数、总成绩; SELECT student.sid, student.sname, count(s.corse_id), sum(s.number) FROM student LEFT JOIN score s ON student.sid = s.student_id GROUP BY student.sid; # 查询姓“李”的老师的个数; SELECT count(tid) FROM teacher WHERE tname LIKE "李%"; # 查询没学过“叶平”老师课的同学的学号、姓名; SELECT sid, sname FROM student WHERE sid NOT IN ( SELECT DISTINCT student_id FROM score WHERE corse_id IN ( SELECT course.cid FROM course LEFT JOIN teacher t ON course.tearch_id = t.tid WHERE t.tname = "叶平" )); # 查询学过“001”并且也学过编号“002”课程的同学的学号、姓名; SELECT tb2.sid, tb2.sname FROM (SELECT student_id, corse_id FROM score WHERE corse_id = 2 OR corse_id = 3) AS tb1 LEFT JOIN student tb2 ON tb2.sid = tb1.student_id GROUP BY student_id HAVING count(student_id) > 1; # 查询学过“叶平”老师所教的所有课的同学的学号、姓名; SELECT student.sid, student.sname FROM student WHERE sid IN ( SELECT DISTINCT student_id FROM score WHERE corse_id IN ( SELECT course.cid FROM course LEFT JOIN teacher t ON course.tearch_id = t.tid WHERE t.tname = \'苍空\') ); # 9.查询课程编号“002”的成绩比课程编号“001”课程低的所有同学的学号、姓名; # 跟第一题差不多 # 查询有课程成绩小于60分的同学的学号、姓名; SELECT student.sid, student.sname FROM student WHERE sid IN ( SELECT DISTINCT student_id FROM score WHERE number < 60 ); # 查询没有学全所有课的同学的学号、姓名; SELECT sid, sname FROM student WHERE sid IN ( SELECT student_id FROM score GROUP BY student_id HAVING count(number) = ( SELECT COUNT(1) FROM course)); SELECT s.sid, s.sname FROM score LEFT JOIN student s ON score.student_id = s.sid GROUP BY score.student_id HAVING count(number) = (SELECT count(1) FROM course); # 查询至少有一门课与学号为“001”的同学所学相同的同学的学号和姓名; # 1 先找到001同学所学的所有课程id # 2.条件学号不为1 以及所学课程in 1号学生所学的id里面 SELECT s.sid, s.sname FROM score LEFT JOIN student s ON score.student_id = s.sid WHERE student_id != 1 AND score.corse_id IN ( SELECT corse_id FROM score WHERE student_id = 1) GROUP BY student_id; # 查询至少学过学号为“002”同学所有课的其他同学学号和姓名; SELECT student_id, sname, count(score.corse_id) FROM score LEFT JOIN student s ON score.student_id = s.sid WHERE score.student_id != 2 AND score.corse_id IN ( SELECT corse_id FROM score WHERE student_id = 2) GROUP BY student_id HAVING count(corse_id) = (SELECT count(corse_id) FROM score WHERE student_id = 2); SELECT student_id, sname, count(corse_id) FROM score LEFT JOIN student ON score.student_id = student.sid WHERE student_id != 1 AND corse_id IN (SELECT corse_id FROM score WHERE student_id = 1) GROUP BY student_id HAVING count(corse_id) = (SELECT count(corse_id) FROM score WHERE student_id = 1); # 查询和“001”号的同学学习的课程完全相同的其他同学学号和姓名; # 总个数相等 但 不一定所学的就等于1号所学的 # 2号所学的课程都被学到 但验证不了总个数相等 SELECT student_id, sname FROM score LEFT JOIN student ON score.student_id = student.sid # 总的数量=1号总的数量 WHERE student_id IN (SELECT student_id FROM score WHERE student_id != 2 GROUP BY student_id HAVING count(corse_id) = (SELECT count(1) FROM score WHERE student_id = 2)) AND corse_id IN ( # 1号所学的课程数量都已被学到 SELECT corse_id FROM score WHERE corse_id IN (SELECT corse_id FROM score WHERE student_id = 2) GROUP BY student_id HAVING count(corse_id) = (SELECT count(*) FROM score WHERE student_id = 2) ); # 15、删除学习“叶平”老师课的score表记录; DELETE FROM score WHERE score.corse_id IN (SELECT cid FROM course LEFT JOIN teacher t ON course.tearch_id = t.tid WHERE t.tname = \'叶平\'); # 向SC表中插入一些记录,这些记录要求符合以下条件: # ①没有上过编号“002”课程的同学学号; # ②插入“002”号课程的平均成绩; INSERT INTO score (student_id, corse_id, number) SELECT sid, 2, (SELECT avg(number) FROM score WHERE corse_id = 2) FROM student WHERE sid NOT IN ( SELECT student_id FROM score WHERE corse_id = 2 ); # 17、按平均成绩从低到高 显示所有学生的“语文”、“数学”、“英语”三门的课程成绩,按如下形式显示: 学生ID,语文,数学,英语,有效课程数,有效平均分; SELECT student_id, (SELECT number FROM score LEFT JOIN course c ON score.corse_id = c.cid WHERE c.cname = \'生物\' AND score.student_id = sc.student_id) AS "生物", (SELECT number FROM score LEFT JOIN course c ON score.corse_id = c.cid WHERE c.cname = \'物理\' AND score.student_id = sc.student_id) AS "物理", (SELECT number FROM score LEFT JOIN course c ON score.corse_id = c.cid WHERE c.cname = \'体育\' AND score.student_id = sc.student_id) AS "体育", count(sc.corse_id), avg(number) FROM score AS sc WHERE sc.corse_id IN (SELECT cid FROM course WHERE course.cname = \'生物\' OR course.cname = \'物理\' OR course.cname = \'体育\') GROUP BY sc.student_id ORDER BY avg(number); # 18、查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分; SELECT corse_id, c.cname, max(number), min(number) FROM score LEFT JOIN course c ON score.corse_id = c.cid GROUP BY corse_id; # 19、按各科平均成绩从低到高和及格率的百分数从高到低顺序; # 思路:case when .. then SELECT corse_id, avg(number) AS avgnum, sum(CASE WHEN score.number > 60 THEN 1 ELSE 0 END) / count(1) * 100 AS percent FROM score GROUP BY corse_id ORDER BY avgnum ASC, percent DESC; # 20、课程平均分从高到低显示(显示任课老师) SELECT avg(number), t.tname FROM score LEFT JOIN course c ON score.corse_id = c.cid LEFT JOIN teacher t ON c.tearch_id = t.tid GROUP BY corse_id ORDER BY avg(number) DESC; # 21、查询各科成绩前三名的记录:(不考虑成绩并列情况) # 思路 先找到第一名和第四名的值 SELECT score.sid, score.corse_id, score.number, T.first_num, T.second_num FROM score LEFT JOIN (SELECT sid, (SELECT number FROM score AS s2 WHERE s2.corse_id = s1.corse_id ORDER BY number DESC LIMIT 0, 1) AS first_num, (SELECT number FROM score AS s2 WHERE s2.corse_id = s1.corse_id ORDER BY number DESC LIMIT 3, 1) AS second_num, FROM score AS s1) AS T ON score.sid = T.sid WHERE score.number <= T.first_num AND score.number >= T.second_num; # 22、查询每门课程被选修的学生数; SELECT corse_id, count(1) FROM score GROUP BY corse_id; # 23、查询出只选修了一门课程的全部学生的学号和姓名; SELECT s.sid, s.sname, count(1) FROM score LEFT JOIN student s ON score.student_id = s.sid GROUP BY student_id HAVING count(1) = 1; # 24、查询男生、女生的人数; # 男生总数为一张表 女生总数为一张表,每张表里面都只有一个字段 # 查询两张表 SELECT * FROM (SELECT count(1) AS man FROM student WHERE student.gender = \'男\') AS A, (SELECT count(1) AS wuman FROM student WHERE student.gender = \'女\') AS B # 25、查询姓“张”的学生名单; SELECT * FROM student WHERE sname LIKE \'张%\'; # 26、查询同名同姓学生名单,并统计同名人数; SELECT sname, count(1) FROM student GROUP BY sname; # 27、查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列; SELECT corse_id, avg(if(isnull(number), 0, number)) AS avg FROM score GROUP BY corse_id ORDER BY avg ASC, corse_id DESC # 28、查询平均成绩大于85的所有学生的学号、姓名和平均成绩; SELECT s.sid, s.sname, avg(if(isnull(number), 0, number)) AS avg FROM score LEFT JOIN student s ON score.student_id = s.sid GROUP BY student_id HAVING avg > 85; # 29、查询课程名称为“数学”,且分数低于60的学生姓名和分数; SELECT s.sid, s.sname, score.number FROM score LEFT JOIN student s ON score.student_id = s.sid LEFT JOIN course c ON score.corse_id = c.cid WHERE c.cname = \'数学\' AND number < 60; # 30、查询课程编号为003且课程成绩在80分以上的学生的学号和姓名; SELECT s.sid, s.sname, score.number, score.corse_id FROM score LEFT JOIN student s ON score.student_id = s.sid WHERE corse_id = \'3\' AND number > 80; # 31、求选了课程的学生人数 # 第一种做法 SELECT count(DISTINCTLeetCode刷题 -- 二叉树练习篇