Eva_J链接:
上课链接: https://www.cnblogs.com/Eva-J/articles/10544358.html
作业链接:
1. 数据库小考: https://www.cnblogs.com/Eva-J/articles/11074845.html
2. 多表查询: https://www.cnblogs.com/Eva-J/articles/9688383.html
作业需求:
第一部分:


# 0.建表book,并向表中插入数据 # 1.查询egon写的所有书和价格 # 2.找出最贵的图书的价格 # 3.求所有图书的均价 # 4.将所有图书按照出版日期排序 # 5.查询alex写的所有书的平均价格 # 6.查询人民音乐不好听出版社出版的所有图书 # 7.查询人民音乐出版社出版的alex写的所有图书和价格 # 8.找出出版图书均价最高的作者 # 9.找出最新出版的图书的作者和出版社 # 10.显示各出版社出版的所有图书 # 11.查找价格最高的图书,并将它的价格修改为50元 # 12.删除价格最低的那本书对应的数据 # 13.将所有alex写的书作业修改成alexsb # 14.select year(publish_date) from book # 自己研究上面sql语句中的year函数的功能,完成需求: # 将所有2017年出版的图书从数据库中删除 # 15.有文件如下,请根据链接自学pymysql模块,使用python写代码将文件中的数据写入数据库 # 学python从开始到放弃|alex|人民大学出版社|50|2018-7-1 # 学mysql从开始到放弃|egon|机械工业出版社|60|2018-6-3 # 学html从开始到放弃|alex|机械工业出版社|20|2018-4-1 # 学css从开始到放弃|wusir|机械工业出版社|120|2018-5-2 # 学js从开始到放弃|wusir|机械工业出版社|100|2018-7-30


-- ---------------------------- -- 创建book_db库 -- ---------------------------- DROP DATABASE IF EXISTS `book_db`; CREATE DATABASE IF NOT EXISTS book_db default charset utf8 COLLATE utf8_general_ci; -- 进入book_db USE book_db; SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- 0.创建book表 插入数据 -- ---------------------------- DROP TABLE IF EXISTS `book`; DROP TABLE IF EXISTS `book`; CREATE TABLE `book`( `name` char(20) not null, # 书名 `author` char(20) not null, # 作者 `Press` char(20) not null, # 出版社 `price` float(5,1) not null, # 价格 `pub_date` date not null #出版日期 ); insert into `book` values ('倚天屠龙记','egon','北京工业地雷出版社',70,'2019-7-1'), ('九阳神功','alex','人民音乐不好听出版社',5,'2018-7-4'), ('九阴真经','yuan', '北京工业地雷出版社',62,'2017-7-12'), ('九阴白骨爪','jinxin','人民音乐不好听出版社',40,'2019-8-7'), ('独孤九剑','alex','北京工业地雷出版社',12,'2017-9-1'), ('降龙十巴掌','egon','知识产权没有用出版社',20,'2019-7-5'), ('葵花宝典','yuan', '知识产权没有用出版社',33,'2019-8-2') ; commit;


-- 1.查询egon写的所有书和价格 SELECT name 书名, price 价格 from book where author = 'egon'; -- 2.找出最贵的图书的价格 select max(price) from book; -- 3.求所有图书的均价 select avg(price) 平均价格 from book; -- 4.将所有图书按照出版日期排序 select * from book order by pub_date; -- 5.查询alex写的所有书的平均价格 select author 作者, avg(price) 平均价格 from book where author='alex'; --6.查询人民音乐不好听出版社出版的所有图书 select * from book where press='人民音乐不好听出版社'; -- 7.查询人民音乐出版社出版的alex写的所有图书和价格 SELECT name 书名, price 价格 from book where author = 'alex' and press='人民音乐不好听出版社'; -- 8.找出出版图书均价最高的作者 select author 作者, avg(price) 价格 from book group by author order by avg(price) desc limit 1; -- 9.找出最新出版的图书的作者和出版社 select name,author,press,pub_date from book order by pub_date desc limit 1; -- 10.显示各出版社出版的所有图书 SELECT Press,GROUP_CONCAT( NAME ) FROM book GROUP BY press; -- 11.查找价格最高的图书,并将它的价格修改为50元 update book set price=50 order by price desc limit 1; -- 12.删除价格最低的那本书对应的数据 delete from book order by price limit 1; -- 13.将所有alex写的书作业修改成alexsb update book set author='alexsb' where author='alex'; -- 14.select year(publish_date) from book -- 自己研究上面sql语句中的year函数的功能,完成需求: -- 将所有2017年出版的图书从数据库中删除 delete from book where year(pub_date)= '2017';


#!/usr/bin/python # -*- coding:utf-8 -*- # Author :王刘俊 import pymysql # 数据库连接信息 conn = pymysql.connect( host='127.0.0.1', user='root', password="123456", database='book_db', port=3306 ) cursor = conn.cursor() try: with open('book', encoding='utf-8') as f: for line in f: book_tu = tuple(line.strip().split('|')) sql = "insert into book values %s" % str(book_tu) cursor.execute(sql) conn.commit() # 提交事务 except: conn.rollback() conn.close()
第二部分:
基础版:


# 1、查询男生、女生的人数; # 2、查询姓“张”的学生名单; # 3、课程平均分从高到低显示 # 4、查询有课程成绩小于60分的同学的学号、姓名; # 5、查询至少有一门课与学号为1的同学所学课程相同的同学的学号和姓名; # 6、查询出只选修了一门课程的全部学生的学号和姓名; # 7、查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分; # 8、查询课程编号“2”的成绩比课程编号“1”课程低的所有同学的学号、姓名; # 9、查询“生物”课程比“物理”课程成绩高的所有学生的学号; # 10、查询平均成绩大于60分的同学的学号和平均成绩; # 11、查询所有同学的学号、姓名、选课数、总成绩; # 12、查询姓“李”的老师的个数; # 13、查询没学过“张磊老师”课的同学的学号、姓名; # 14、查询学过“1”并且也学过编号“2”课程的同学的学号、姓名; # 15、查询学过“李平老师”所教的所有课的同学的学号、姓名;


--1、查询男生、女生的人数; select gender , count(sid) from student group by gender; --2、查询姓“张”的学生名单; select * from student where sname like '张%'; --3、课程平均分从高到低显示 select sc.course_id,co.cname, sc.num from score sc left join course co on co.cid = sc.course_id group by sc.course_id order by sc.num desc; --4、查询有课程成绩小于60分的同学的学号、姓名; select stu.sid 学号,stu.sname 姓名,min(sc.num) 最小成绩 from student stu left join score sc on sc.student_id = stu.sid group by stu.sid having min(sc.num) < 60; --5、查询至少有一门课与学号为1的同学所学课程相同的同学的学号和姓名 SELECT a.student_id, stu.sname FROM score as a LEFT JOIN student stu ON stu.sid = a.student_id WHERE a.course_id in (SELECT b.course_id FROM score AS b WHERE b.student_id = 1) GROUP BY a.student_id; -- having a.student_id <> 1 --如果要去掉学号1本身 --6、查询出只选修了一门课程的全部学生的学号和姓名; select student_id,stu.sname from score sc left join student stu on stu.sid = sc.student_id group by student_id having count(*) =1; --7、查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分; select course_id ,max(num) highest, min(num) lowest from score group by course_id; --8、查询课程编号“2”的成绩比课程编号“1”课程低的所有同学的学号、姓名; -- 写法1 SELECT a.student_id, stu.sname,a.num AS score1, b.num AS score2 FROM score a LEFT JOIN score b ON a.student_id = b.student_id LEFT JOIN student stu ON stu.sid = a.student_id WHERE a.course_id = 1 AND b.course_id = 2 GROUP BY a.student_id HAVING score1 > score2; -- 写法2 SELECT tmp.student_id, stu.sname,sum(score1) sco1, sum(score2) sco2 FROM ( SELECT student_id, CASE WHEN course_id = 1 THEN num END score1, CASE WHEN course_id = 2 THEN num END score2 FROM score ) tmp LEFT JOIN student stu ON stu.sid = tmp.student_id GROUP BY student_id HAVING sco1 > sco2; --9、查询“生物”课程比“物理”课程成绩高的所有学生的学号; SELECT tmp.student_id,sum(score1) sco1, sum(score2) sco2 FROM ( SELECT student_id, CASE WHEN course_id = (SELECT cid FROM course WHERE cname ='生物' ) THEN num END score1, CASE WHEN course_id = (SELECT cid FROM course WHERE cname ='物理' ) THEN num END score2 FROM score ) tmp GROUP BY student_id HAVING sco1 > sco2; --10、查询平均成绩大于60分的同学的学号和平均成绩; SELECT student_id,avg(num) avg_sore from score group by student_id; --11、查询所有同学的学号、姓名、选课数、总成绩; select student_id, count(student_id) total_num, sum(num) total_sco from score group by student_id; --12、查询姓“李”的老师的个数; select count(tid) from teacher where tname like '李%'; --13、查询没学过“张磊老师”课的同学的学号、姓名; SELECT sid,sname FROM student WHERE sid not in ( SELECT student_id FROM course co LEFT JOIN score sc ON co.cid = sc.course_id LEFT JOIN teacher tea ON tea.tid = co.teacher_id WHERE tea.tname = '张磊老师' GROUP BY student_id ) --14、查询学过“1”并且也学过编号“2”课程的同学的学号、姓名; SELECT sc.student_id,stu.sname FROM score sc LEFT JOIN student stu ON stu.sid = sc.student_id WHERE sc.course_id IN(1,2) GROUP BY sc.student_id HAVING COUNT(student_id) = 2 --15、查询学过“李平老师”所教的所有课的同学的学号、姓名; SELECT student_id, stu.sname FROM course co LEFT JOIN score sc ON co.cid = sc.course_id LEFT JOIN teacher tea ON tea.tid = co.teacher_id LEFT JOIN student stu ON stu.sid = student_id WHERE tea.tname = '李平老师' GROUP BY student_id HAVING COUNT( student_id ) = ( SELECT COUNT( co.cid ) FROM course co LEFT JOIN teacher tea ON tea.tid = co.teacher_id WHERE tea.tname = '李平老师' )
进阶版:


1、查询没有学全所有课的同学的学号、姓名; # 2、查询和“002”号的同学学习的课程完全相同的其他同学学号和姓名; # 3、删除学习“叶平”老师课的SC表记录; # 4、向SC表中插入一些记录,这些记录要求符合以下条件:①没有上过编号“002”课程的同学学号;②插入“002”号课程的平均成绩; # 5、按平均成绩从低到高显示所有学生的“语文”、“数学”、“英语”三门的课程成绩,按如下形式显示: 学生ID,语文,数学,英语,有效课程数,有效平均分; # 6、查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分; # 7、按各科平均成绩从低到高和及格率的百分数从高到低顺序; # 8、查询各科成绩前三名的记录:(不考虑成绩并列情况) # 9、查询每门课程被选修的学生数; # 10、查询同名同姓学生名单,并统计同名人数; # 11、查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列; # 12、查询平均成绩大于85的所有学生的学号、姓名和平均成绩; # 13、查询课程名称为“数学”,且分数低于60的学生姓名和分数; # 14、查询课程编号为003且课程成绩在80分以上的学生的学号和姓名; # 15、求选了课程的学生人数 # 16、查询选修“杨艳”老师所授课程的学生中,成绩最高的学生姓名及其成绩; # 17、查询各个课程及相应的选修人数; # 18、查询不同课程但成绩相同的学生的学号、课程号、学生成绩; # 19、查询每门课程成绩最好的前两名; # 20、检索至少选修两门课程的学生学号; # 21、查询全部学生都选修的课程的课程号和课程名; # 22、查询没学过“叶平”老师讲授的任一门课程的学生姓名; # 23、查询两门以上不及格课程的同学的学号及其平均成绩; # 24、检索“004”课程分数小于60,按分数降序排列的同学学号; # 25、删除“002”同学的“001”课程的成绩;


-- 1、查询没有学全所有课的同学的学号、姓名; SELECT sc.student_id, stu.sname FROM score sc LEFT JOIN student stu ON stu.sid = sc.student_id GROUP BY sc.student_id HAVING COUNT( student_id ) != ( SELECT count( cid ) FROM course ); -- 2、查询和“002”号的同学学习的课程完全相同的其他同学学号和姓名; SELECT student_id, stu.sname FROM score sc LEFT JOIN student stu ON stu.sid = sc.student_id GROUP BY student_id HAVING GROUP_CONCAT( sc.course_id ) = ( SELECT GROUP_CONCAT( sc.course_id ) FROM score sc WHERE student_id = '002' ) AND student_id != '002'; -- 3、删除学习“叶平”老师课的SC表记录; DELETE FROM score WHERE course_id IN ( SELECT co.cid FROM course co LEFT JOIN teacher tea ON tea.tid = co.teacher_id WHERE tea.tname = '叶平' ); -- 4、向SC表中插入一些记录,这些记录要求符合以下条件: --①没有上过编号“002”课程的同学学号;②-插入“002”号课程的平均成绩; SELECT * FROM student WHERE sid not in( -- 1.查询没有上过002课程的同学学号 SELECT student_id FROM score WHERE course_id = 002 ); SELECT AVG(num) FROM score WHERE course_id = '002'; -- 2.查询002 平均成绩 INSERT INTO score(student_id,course_id,num) -- 3.插入数据 VALUES (2,002,65),(13,002,65),(14,002,65); -- 5、按平均成绩从低到高显示所有学生的“语文”、“数学”、“英语”三门的课程成绩, --按如下形式显示:学生ID,语文,数学,英语,有效课程数,有效平均分; SELECT sc.student_id, SUM( CASE WHEN course_id = ( SELECT cid FROM course WHERE cname = '生物' ) THEN num END ) '生物', SUM( CASE WHEN course_id = ( SELECT cid FROM course WHERE cname = '物理' ) THEN num END ) '物理', SUM( CASE WHEN course_id = ( SELECT cid FROM course WHERE cname = '体育' ) THEN num END ) '体育', count_num, avg_num FROM score sc LEFT JOIN ( SELECT student_id, avg( num ) avg_num, COUNT( num ) count_num FROM score GROUP BY student_id) temp ON sc.student_id = temp.student_id GROUP BY sc.student_id ORDER BY avg_num; -- 6、查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分; SELECT course_id, max( num ) max_num, min( num ) min_num FROM score GROUP BY course_id -- 7、按各科平均成绩从低到高和及格率的百分数从高到低顺序; SELECT course_id, avg(num) -- 按各科平均成绩从低到高 FROM score sc GROUP BY course_id ORDER BY avg(num); SELECT course_id, -- 及格率的百分数从高到低顺序 CONCAT(ROUND(COUNT(CASE WHEN num < 60 THEN num END)/COUNT(sid)*100,2),'%') '及格率' FROM score GROUP BY course_id ORDER BY COUNT(CASE WHEN num < 60 THEN num END)/COUNT(num) DESC ; -- 8、查询各科成绩前三名的记录:(不考虑成绩并列情况) SELECT course_id, (SELECT num FROM score sc WHERE sc.course_id = A.course_id ORDER BY sc.course_id, sc.num DESC LIMIT 1 ) '第一名', (SELECT num FROM score sc WHERE sc.course_id = A.course_id ORDER BY sc.course_id, sc.num DESC LIMIT 1,1 ) '第二名', ( SELECT num FROM score sc WHERE sc.course_id = A.course_id ORDER BY sc.course_id, sc.num DESC LIMIT 2,1 ) '第三名' FROM score A GROUP BY course_id; -- 9、查询每门课程被选修的学生数; SELECT course_id,count(DISTINCT student_id) count_num FROM score GROUP BY course_id; -- 10、查询同名同姓学生名单,并统计同名人数; SELECT sname, count(sid) FROM student GROUP BY sname; -- 11、查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列; SELECT course_id, avg(num) avg_num from score group by course_id order by avg_num ASC,course_id DESC; -- 12、查询平均成绩大于85的所有学生的学号、姓名和平均成绩; SELECT student_id,sname,AVG(num) avg_num from score LEFT JOIN student stu on stu.sid=student_id GROUP BY student_id HAVING avg_num > 85; -- 13、查询课程名称为“数学”,且分数低于60的学生姓名和分数; SELECT stu.sname, sc.num FROM score sc LEFT JOIN student stu ON stu.sid = sc.student_id LEFT JOIN course co ON co.cid = sc.course_id WHERE co.cname = '物理' AND sc.num <60; -- 14、查询课程编号为003且课程成绩在80分以上的学生的学号和姓名; SELECT stu.sname, sc.num FROM score sc LEFT JOIN student stu ON stu.sid = sc.student_id WHERE course_id='003' AND sc.num > 80; -- 15、求选了课程的学生人数 SELECT SUM( sid IN ( SELECT student_id FROM score sc GROUP BY sc.student_id ) ) FROM student; -- 16、查询选修“杨艳”老师所授课程的学生中,成绩最高的学生姓名及其成绩; SELECT student.sid ,student.sname ,num FROM score LEFT JOIN course ON score.course_id=course.cid LEFT JOIN student ON score.student_id=student.sid LEFT JOIN teacher ON course.teacher_id=teacher.tid WHERE teacher.tname = "李平老师" ORDER BY num DESC LIMIT 1; -- 17、查询各个课程及相应的选修人数; SELECT course_id, co.cname, COUNT( student_id ) FROM score sc LEFT JOIN course co ON co.cid = sc.course_id GROUP BY course_id; -- 18、查询不同课程但成绩相同的学生的学号、课程号、学生成绩; SELECT A.student_id,A.course_id,B.num,B.student_id,B.course_id,B.num FROM score A,score B WHERE A.course_id <> B.course_id AND A.num = B.num ORDER BY A.student_id; -- 19、查询每门课程成绩最好的前两名; SELECT co.cname, (SELECT sc.num FROM score sc WHERE sc.course_id = co.cid ORDER BY sc.num DESC LIMIT 1) '第一名', (SELECT sc.num FROM score sc WHERE sc.course_id = co.cid ORDER BY sc.num DESC LIMIT 1,1) '第二名' FROM course co ; -- 20、检索至少选修两门课程的学生学号; SELECT student_id, count(sid) cou_cour FROM score group by student_id having cou_cour >= 2; -- 21、查询全部学生都选修的课程的课程号和课程名; SELECT course_id, co.cname FROM score LEFT JOIN course co ON co.cid = score.course_id GROUP BY course_id HAVING COUNT( student_id ) = ( SELECT COUNT( sid ) FROM student ); -- 22、查询没学过“叶平”老师讲授的任一门课程的学生姓名; SELECT sid, sname FROM student WHERE sid NOT IN (SELECT student_id FROM score sc INNER JOIN course co ON co.cid = sc.course_id INNER JOIN teacher tea ON tea.tid = co.teacher_id WHERE tea.tname = '李平老师' GROUP BY student_id ); -- 23、查询两门以上不及格课程的同学的学号及其平均成绩; SELECT student_id,COUNT(num) no_pass, (SELECT AVG(A.num) FROM score A WHERE A.student_id = sc.student_id GROUP BY A.student_id ) '平均分' FROM score sc WHERE num <60 GROUP BY student_id HAVING no_pass > 1 ; -- 24、检索“004”课程分数小于60,按分数降序排列的同学学号; SELECT stu.sid, sname, num FROM score sc LEFT JOIN student stu ON stu.sid = sc.student_id WHERE course_id = '004' AND num < 60 ORDER BY num DESC; -- 25、删除“002”同学的“001”课程的成绩; SELECT * FROM score -- DELETE FROM score WHERE student_id = '002' AND course_id = '001';