1.数据准备

以下为db文件,通过Navicat Premium导入数据库

/*
数据导入:
Navicat Premium Data Transfer Source Server : localhost
Source Server Type : MySQL
Source Server Version : 50624
Source Host : localhost
Source Database : sqlexam Target Server Type : MySQL
Target Server Version : 50624
File Encoding : utf-8 Date: 10/21/2016 06:46:46 AM
*/ SET NAMES utf8;
SET FOREIGN_KEY_CHECKS = 0; -- ----------------------------
-- Table structure for `class`
-- ----------------------------
DROP TABLE IF EXISTS `class`;
CREATE TABLE `class` (
`cid` int(11) NOT NULL AUTO_INCREMENT,
`caption` varchar(32) NOT NULL,
PRIMARY KEY (`cid`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; -- ----------------------------
-- Records of `class`
-- ----------------------------
BEGIN;
INSERT INTO `class` VALUES ('', '三年二班'), ('', '三年三班'), ('', '一年二班'), ('', '二年九班');
COMMIT; -- ----------------------------
-- Table structure for `course`
-- ----------------------------
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course` (
`cid` int(11) NOT NULL AUTO_INCREMENT,
`cname` varchar(32) NOT NULL,
`teacher_id` int(11) NOT NULL,
PRIMARY KEY (`cid`),
KEY `fk_course_teacher` (`teacher_id`),
CONSTRAINT `fk_course_teacher` FOREIGN KEY (`teacher_id`) REFERENCES `teacher` (`tid`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; -- ----------------------------
-- Records of `course`
-- ----------------------------
BEGIN;
INSERT INTO `course` VALUES ('', '生物', ''), ('', '物理', ''), ('', '体育', ''), ('', '美术', '');
COMMIT; -- ----------------------------
-- Table structure for `score`
-- ----------------------------
DROP TABLE IF EXISTS `score`;
CREATE TABLE `score` (
`sid` int(11) NOT NULL AUTO_INCREMENT,
`student_id` int(11) NOT NULL,
`course_id` int(11) NOT NULL,
`num` int(11) NOT NULL,
PRIMARY KEY (`sid`),
KEY `fk_score_student` (`student_id`),
KEY `fk_score_course` (`course_id`),
CONSTRAINT `fk_score_course` FOREIGN KEY (`course_id`) REFERENCES `course` (`cid`),
CONSTRAINT `fk_score_student` FOREIGN KEY (`student_id`) REFERENCES `student` (`sid`)
) ENGINE=InnoDB AUTO_INCREMENT=53 DEFAULT CHARSET=utf8; -- ----------------------------
-- Records of `score`
-- ----------------------------
BEGIN;
INSERT INTO `score` VALUES ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', ''), ('', '', '', '');
COMMIT; -- ----------------------------
-- Table structure for `student`
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`sid` int(11) NOT NULL AUTO_INCREMENT,
`gender` char(1) NOT NULL,
`class_id` int(11) NOT NULL,
`sname` varchar(32) NOT NULL,
PRIMARY KEY (`sid`),
KEY `fk_class` (`class_id`),
CONSTRAINT `fk_class` FOREIGN KEY (`class_id`) REFERENCES `class` (`cid`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8; -- ----------------------------
-- Records of `student`
-- ----------------------------
BEGIN;
INSERT INTO `student` VALUES ('', '男', '', '理解'), ('', '女', '', '钢蛋'), ('', '男', '', '张三'), ('', '男', '', '张一'), ('', '女', '', '张二'), ('', '男', '', '张四'), ('', '女', '', '铁锤'), ('', '男', '', '李三'), ('', '男', '', '李一'), ('', '女', '', '李二'), ('', '男', '', '李四'), ('', '女', '', '如花'), ('', '男', '', '刘三'), ('', '男', '', '刘一'), ('', '女', '', '刘二'), ('', '男', '', '刘四');
COMMIT; -- ----------------------------
-- Table structure for `teacher`
-- ----------------------------
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` (
`tid` int(11) NOT NULL AUTO_INCREMENT,
`tname` varchar(32) NOT NULL,
PRIMARY KEY (`tid`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; -- ----------------------------
-- Records of `teacher`
-- ----------------------------
BEGIN;
INSERT INTO `teacher` VALUES ('', '张磊老师'), ('', '李平老师'), ('', '刘海燕老师'), ('', '朱云海老师'), ('', '李杰老师');
COMMIT; SET FOREIGN_KEY_CHECKS = 1;

2.练习题

-- 1、查询所有的课程的名称以及对应的任课老师姓名
select cname,tname from course inner join teacher on course.teacher_id = teacher.tid -- 2、查询学生表中男女生各有多少人
select gender,count(gender) from student group by gender -- 3、查询物理成绩等于100的学生的姓名
-- 第四步:与学生表拼接,拿到学生姓名
select student.sid,gender,sname,num from student inner join(
select * from (
-- 第一步:查询分数为100的表
select * from score where num = 100 )as t1
-- 第三步:条件筛选出物理分数100的表
where t1.course_id = (
-- 第二步:查询物理的id
select cid from course where cname = '物理')
# 拼接
) as t2 on t2.student_id = student.sid -- 4、查询平均成绩大于八十分的同学的姓名和平均成绩
-- 第二步:拼表
select sname, num from student inner join (
-- 第一步:以学生id为分组,筛选分数表中的成绩
select student_id,avg(num)as 'num' from score group by student_id having avg(num)>80
)as t1 on student.sid = t1.student_id -- 5、查询所有学生的学号,姓名,选课数,总成绩
-- 第三步:拼表筛选
select t1.student_id,t2.sname,t1.数量,t1.总成绩 from (
-- 第二部筛选分数表,并计数
select student_id,count(num)as '数量',sum(num)as '总成绩' from score group by student_id)as t1
inner join (
-- 第一步:筛选学生表
select sid,sname from student)as t2 on t1.student_id = t2.sid -- 6、 查询姓李老师的个数
select count(tname)as '姓李的数量' from teacher where tname like '李%' -- 7、 查询没有报李平老师课的学生姓名
-- 第四步:根据学生id取反拿到没有选择李平老师课程的学生
select sname from student where sid not in (
-- 第三步:拿到选择李平老师课程的学生id
select distinct student_id from score where course_id in (
-- 第二步:根据老师id拿到老师教的课程id
select cid from course where teacher_id = (
-- 第一步:拿到李平老师的id
select tid from teacher where tname = '李平老师'))) -- 8、 查询物理课程比生物课程高的学生的学号
-- 第五步:拼接两张表
select * from (
-- 第二步:查询物理的所有成绩
select student_id as '学生物理id',num as '物理成绩' from score where course_id = (
-- 第一步:查询物理的id
select cid from course where cname = '物理' ))as t1
inner join (
-- 第四步:查询生物的所有成绩
select student_id as '学生生物id',num as '生物成绩' from score where course_id = (
-- 第三步:查询生物的id
select cid from course where cname = '生物' ))as t2
on t1.学生物理id = t2.学生生物id
-- 第六步:筛选物理大于生物
where 物理成绩 > 生物成绩 -- 9、 查询没有同时选修物理课程和体育课程的学生姓名
-- 第四步:根据拿到的学号从学生表中获取想要的数据
select sid,sname from student where sid in (
-- 第三步:以学号为组,计数为1,意思是物理体育只有一门,筛选得到学号
select t1.student_id from (
-- 第一步,简单粗暴,直接把相关的表拼起来
select * from score inner join course on score.course_id = course.cid
-- 第二步,筛选课程
where cname in ('物理','体育')
)as t1
group by t1.student_id
having count(student_id)=1
) -- 10、查询挂科超过两门(包括两门)的学生姓名和班级
-- 第四步:和班级表拼接,拿到想要的字段
select caption,sname,挂科数 from class inner join (
-- 第三步:与学生表拼接,拿出想要的字段
select * from student inner join (
-- 第一步:筛选出小于60分的所有成绩名单
select student_id,count(student_id)as'挂科数' from score where num < 60
-- 第二步: 以学生为分组,查看这个学生60分以下出现了多少次,就是多少门不及格
group by student_id having count(student_id)>=1
-- 拼接
)as t1 on student.sid = t1.student_id
) as t2 on class.cid = t2.class_id -- 11、查询选修了所有课程的学生姓名
-- 第四步:和学生表拼接,拿到想要的字段
select sname,课程数 from student inner join (
-- 第二步:以学生为分组,计算所有学生选择的课程数
select student_id,count(student_id)as'课程数' from score group by student_id
-- 第三步:筛选学生选择的课程数=课程总数
having count(student_id) = (
-- 第一步:拿到所有课程的id
select count(cid)as'总课程数' from course )
-- 拼接
)as t1 on student.sid = t1.student_id -- 12、查询李平老师教的课程的所有成绩记录
-- 第三步:在与分数表拼接,拿到想要的字段信息
select tname,student_id,cname,num from score inner join (
-- 第二步:课程表和李平老师信息表拼接
select * from course inner join (
-- 第一步:拿到李平老师的信息
select * from teacher where tname = '李平老师'
-- 拼接
)as t1 on course.teacher_id = t1.tid
-- 拼接
)as t2 on score.course_id = t2.cid -- 13、查询全部学生都选修了的课程号和课程名
-- 第二步:在和课程表拼接起来,选择想要的字段
select student_id,sname,gender,cid,cname,num from course inner join (
-- 第一步:把分数表和学生表拼起来,选择想要的字段
select score.student_id,student.gender,student.sname,score.course_id,score.num from score inner join student on score.student_id = student.sid
-- 拼接
)as t1 on course.cid = t1.course_id -- 14、查询每门课程被选修的次数
第二步:筛选过的表与课程表拼接,获取课程名
select cid,cname, 被选次数 from course inner join (
-- 第一步:以课程id为组,查询被选的次数
select course_id,count(course_id)as'被选次数' from score group by course_id
) as t1 on course.cid = t1.course_id -- 15、查询只选修了一门课程的学生姓名和学号
-- 第二步:拼接学生表,获取信息
select sid,sname,选课门数 from student inner join(
-- 第一步:以学生为分组,查询选课数为1的
select student_id,count(student_id)as '选课门数' from score group by student_id
having count(student_id) = 1
-- 拼接
) as t1 on student.sid = t1.student_id -- 16、查询所有学生考出的成绩并按从高到低排序(成绩去重)
-- 第二步:和学生表拼接,获取想要的字段信息
select sid,sname,总成绩 from student inner join (
-- 第一步:查询所有学生的总成绩
select student_id,sum(num)as '总成绩' from score group by student_id
-- 拼接
)as t1 on student.sid = t1.student_id
-- 降序排名
order by 总成绩 desc -- 17、查询平均成绩大于85的学生姓名和平均成绩
-- 第二步:和学生表拼接,获取想要的字段
select sname,avg as '平均成绩' from student inner join (
-- 第一步:以学生id为分组 查询大于85分的信息
select student_id,avg(num)as 'avg' from score group by student_id having avg(num)>85
) as t1 on student.sid = t1.student_id -- 18、查询生物成绩不及格的学生姓名和对应生物分数
-- 第四步:拼接学生表获取想要的信息
select sname,num as '不及格生物分数' from student inner join (
-- 第二步:查询所有的生物成绩
select * from score where course_id = (
-- 第一步:查询生物的id
select cid from course where cname = '生物')
-- 第三步:筛选分数不及格的
and num<60
)as t1 on student.sid = t1.student_id -- 19、查询在所有选修了李平老师课程的学生中,这些课程(李平老师的课程,不是所有课程)平均成绩最高的学生姓名
select sname,平均值 from student inner join (
-- 第五步:根据所有学生的平均成绩选出最大成绩,排序,取第一名
select t2.student_id,平均值 from (
-- 第四步:求出李平老师所有学生的平均成绩
select t1.student_id ,avg(num)as'平均值' from (
-- 第三步:拿到选择李平老师课程的学生id
select * from score where course_id in (
-- 第二步:根据老师id拿到老师教的课程id
select cid from course where teacher_id = (
-- 第一步:拿到李平老师的id
select tid from teacher where tname = '李平老师'))
-- 接第四步
)as t1 group by t1.student_id
-- 接第五步
)as t2 order by 平均值 desc limit 1
)as t3 on student.sid = t3.student_id; -- 20、查询每门课程成绩最好的前两名学生姓名
-- 错误思路:按照课程id分组,排序,去前两名。分组之后,组里面的数据不能取出来
-- 正确思路:把每一课的成绩分别拎出来,分别取前两名。最后合并表 # 最最后:和学生表拼接,拿到学生姓名
select student.sid,student.sname,t1.num from student inner join (
# 最后一步,用union all,不去重连接所有表
# 生物前两名
-- 第二步:查看生物的所有成绩
(select * from score where course_id in (
-- 第一步:获取所有生物的id号
select cid from course where cname= '生物'
)
-- 第三步:排序,并只显示前两条
order by num desc limit 2)
union all
# 物理前两名
-- 第二步:查看生物的所有成绩
(select * from score where course_id in (
-- 第一步:获取所有生物的id号
select cid from course where cname= '物理'
)
-- 第三步:排序,并只显示前两条
order by num desc limit 2)
union all
# 体育前两名
-- 第二步:查看生物的所有成绩
(select * from score where course_id in (
-- 第一步:获取所有生物的id号
select cid from course where cname= '体育'
)
-- 第三步:排序,并只显示前两条
order by num desc limit 2)
union all
# 美术前两名
-- 第二步:查看生物的所有成绩
(select * from score where course_id in (
-- 第一步:获取所有生物的id号
select cid from course where cname= '美术'
)
-- 第三步:排序,并只显示前两条
order by num desc limit 2) ) as t1 on student.sid = t1.student_id -- 21、查询不同课程但成绩相同的学号,课程号,成绩 -- 第二步:再次和分数表拼接,获取学号
select student_id,course_id,t1.num,相同数量 from score inner join (
-- 第一步:以分数为分组,筛选出分数重复的
select num,count(num)as'相同数量' from score group by num having count(num) >=2
)as t1 on score.num = t1.num -- 22、查询没学过“李平”老师课程的学生姓名以及选修的课程名称;
-- 第四步:根据学生id取反拿到没有选择李平老师课程的学生
select sname from student where sid not in (
-- 第三步:拿到选择李平老师课程的学生id
select distinct student_id from score where course_id in (
-- 第二步:根据老师id拿到老师教的课程id
select cid from course where teacher_id = (
-- 第一步:拿到李平老师的id
select tid from teacher where tname = '李平老师'))) -- 23、查询所有选修了学号为1的同学选修过的一门或者多门课程的同学学号和姓名;
# 这题考小学语文
-- 第三步:在学生表中筛选出学生
select sid,sname from student where sid in (
-- 第二步:查询选修了学号为1的学生,选修过的课程的学生id
select student_id from score where course_id in (
-- 第一步:查询学号为1的同学,选修的课程id
select course_id from score where student_id = 1
)) -- 24、任课最多的老师中学生单科成绩最高的学生姓名
# 这题考小学语文 -- 实现思路:1.获取授课老师最多的老师id
-- 2.查看该老师教授的课程id
-- 3.查询教授课程对应的所有分数
-- (难点)4.从查询出的分数表,选出最大值的分数
-- (难点,分数相同)5.拿到最大分数再到第3分数表中,查询一致的分数对应的所有信息
-- 6.再和学生表拼接,拿到学生姓名
# 这是第3步筛选之后的表
select * from score where course_id in (
-- 第四步:查看该老师教授的课程id
select cid from course where teacher_id in(
-- 第三步:获取任课数量最多的老师id
select t1.teacher_id from (
-- 第一步:在课程表当中,给选择的课程数量计数
select teacher_id,count(teacher_id)as '数量' from course group by teacher_id
-- 第二步:排序
order by 数量 desc limit 1
)as t1
)) # 这是最大分数
select max(num) from score where course_id in (
-- 第四步:查看该老师教授的课程id
select cid from course where teacher_id in(
-- 第三步:获取任课数量最多的老师id
select t3.teacher_id from (
-- 第一步:在课程表当中,给选择的课程数量计数
select teacher_id,count(teacher_id)as '数量' from course group by teacher_id
-- 第二步:排序
order by 数量 desc limit 1
)as t3
)) # 最终答案
# 与学生表拼接
select student.sid,student.sname,t4.num from student inner join (
# 获取最大分数对应的信息
select * from (
select * from score where course_id in (
-- 第四步:查看该老师教授的课程id
select cid from course where teacher_id in(
-- 第三步:获取任课数量最多的老师id
select t1.teacher_id from (
-- 第一步:在课程表当中,给选择的课程数量计数
select teacher_id,count(teacher_id)as '数量' from course group by teacher_id
-- 第二步:排序,获取最大数量
order by 数量 desc limit 1
)as t1
))
)as t2 where t2.num = (
-- 第五步:查询分数表,教授课程对应的所有分数
# 这里获取最大值分数
select max(num) from score where course_id in (
-- 第四步:查看该老师教授的课程id
select cid from course where teacher_id in(
-- 第三步:获取任课数量最多的老师id
select t3.teacher_id from (
-- 第一步:在课程表当中,给选择的课程数量计数
select teacher_id,count(teacher_id)as '数量' from course group by teacher_id
-- 第二步:排序,获取最大数量
order by 数量 desc limit 1
)as t3
)))
)as t4 on student.sid = t4.student_id

MySQL数据库练习的更多相关文章

  1. nodejs进阶(6)—连接MySQL数据库

    1. 建库连库 连接MySQL数据库需要安装支持 npm install mysql 我们需要提前安装按mysql sever端 建一个数据库mydb1 mysql> CREATE DATABA ...

  2. 当忘记mysql数据库密码时如何进行修改

    因为长时间没有使用数据库了,或者把密码改完之后就忘了数据库密码,不能正常进入数据库,也无法修改密码,有一个简单的常用修改密码方式: 1.首先找到和打开mysql.exe和mysqld.exe所在的文件 ...

  3. MySQL数据库和InnoDB存储引擎文件

    参数文件 当MySQL示例启动时,数据库会先去读一个配置参数文件,用来寻找数据库的各种文件所在位置以及指定某些初始化参数,这些参数通常定义了某种内存结构有多大等.在默认情况下,MySQL实例会按照一定 ...

  4. 一起学微软Power BI系列-使用技巧(1)连接Oracle与Mysql数据库

    说起Oracle数据库,以前没用过Oracle不知道,但是这1年用Oracle后,发现真的是想狂吐槽,特别是那个.NET驱动和链接字符串,特别奇葩.总归是和其他数据库不一样,标新立异,不知道为何.另外 ...

  5. CentOS下mysql数据库常用命令总结

    mysql数据库使用总结 本文主要记录一些mysql日常使用的命令,供以后查询. 1.更改root密码 mysqladmin -uroot password 'yourpassword' 2.远程登陆 ...

  6. [原创]java使用JDBC向MySQL数据库批次插入10W条数据测试效率

    使用JDBC连接MySQL数据库进行数据插入的时候,特别是大批量数据连续插入(100000),如何提高效率呢?在JDBC编程接口中Statement 有两个方法特别值得注意:通过使用addBatch( ...

  7. mysql数据库主从同步

    环境: Mater:   CentOS7.1  5.5.52-MariaDB  192.168.108.133 Slave:   CentOS7.1  5.5.52-MariaDB  192.168. ...

  8. PDO连接mysql数据库

    1.PDO简介 PDO(PHP Data Object) 是PHP 5 中加入的东西,是PHP 5新加入的一个重大功能,因为在PHP 5以前的php4/php3都是一堆的数据库扩展来跟各个数据库的连接 ...

  9. mysql数据库开发常见问题及优化

    mysql 数据库是被广泛应用的关系型数据库,其体积小.支持多处理器.开源并免费的特性使其在 Internet 中小型网站中的使用率尤其高.在使用 mysql 的过程中不规范的 SQL 编写.非最优的 ...

  10. 如何在删除ibdata1和ib_logfile的情况下恢复MySQL数据库

    昨天,有个朋友对公司内部使用的一个MySQL实例开启binlog,但是在启动的过程中失败了(他也没提,为何会失败),在启动失败后,他删除了ibdata1和ib_logfile,后来,能正常启动了,但所 ...

随机推荐

  1. IntelliJ IDEA 快捷键(七)

    /*方法参数提示*/ ctrl + p /*折叠代码/展开代码*/ ctrl + - / ctrl + + /*快速查找和打开最近使用过的文件*/ ctrl + E /*自动代码片*/ ctrl + ...

  2. luoguP2824 [HEOI2016/TJOI2016]排序(线段树分裂做法)

    题意 所谓线段树分裂其实是本题的在线做法. 考虑如果我们有一个已经排好序的区间的权值线段树,那么就可以通过线段树上二分的方法得到第\(k\)个数是谁. 于是用set维护每个升序/降序区间的左右端点以及 ...

  3. ln -s 文件夹变成文件(txt) / linux 链接出错

    问题: 平时没有注意过这这个问题,当我使用ln -s xxx yyy  将xxx 移动到yyy 路径时,文件夹就变成了txt文件, 解决: 找了半天,在stackoverflow上找到了答案,很简单, ...

  4. Phoenix |安装配置| 命令行操作| 与hbase的映射| spark对其读写

    Phoenix Phoenix是HBase的开源SQL皮肤.可以使用标准JDBC API代替HBase客户端API来创建表,插入数据和查询HBase数据. 1.特点 1) 容易集成:如Spark,Hi ...

  5. guava(四)区间Ranges

    一.构建区间 (a..b) open(C, C) [a..b] closed(C, C) [a..b) closedOpen(C, C) (a..b] openClosed(C, C) (a..+∞) ...

  6. 有关tab页的

    有关tab页的 1.静态的 2.动态的可以删除的 3.删除右侧,左侧,全部,除了自己以外的. 4.多了可以自动伸缩. 5.带shown事件.可以反向影响菜单去.

  7. oracle like模糊查询不能走索引?

    这里要纠正一个网上很多教程说的模糊匹配不能走索引的说法,因为在看<收获,不止SQL优化>一书,里面举例说到了,并且自己也跟着例子实践了一下,确实like一些特殊情况也是可以走索引的 例子来 ...

  8. let/const特性

        let: 1.声明的变量不存在预解析: console.log(a); let a=1; 2.变量名不允许重复(在同一作用域下): { let a=1; let a=2; console.lo ...

  9. Java-100天知识进阶-GC算法-知识铺(五)

    知识铺: 致力于打造轻知识点,持续更新每次的知识点较少,阅读不累.不占太多时间,不停的来唤醒你记忆深处的知识点. GC算法 1.标记清除算法 优缺点:不需要额外空间,但是遍历空间花费大,而且会产生大量 ...

  10. 什么是IDE(集成开发环境)?

    实际开发中,除了编译器是必须的工具,我们往往还需要很多其他辅助软件,例如: 编辑器:用来编写代码,并且给代码着色,以方便阅读: 代码提示器:输入部分代码,即可提示全部代码,加速代码的编写过程: 调试器 ...