mysql学习:几十条mysql练习语句(2021-05-02更新)

文章问题导向

mysql单表的数据增删改查如何操作?
如何多表联查?
学完这几十条mysql练习,就可以入门了

如果你都有了答案,可以忽略本文章,或去mysql学习导图寻找更多答案

我的目标:让这个鬼东西变得简单,so easy!!!


学前数据准备:先建5个表,和插入一些数据,用于查询练习

学生表

学号sno
姓名sname
性别ssex
班级class
出生年月sbrithday

create table `student`(
    `sno` varchar(20) primary key,
    `sname` varchar(20) not null,
    `ssex` varchar(10) not null,
    `class` varchar(20),
    `sbirthday` datetime
);

insert into student values('101','大神','男','202001','1988-08-08');
insert into student values('102','李四','男','202002','1988-08-09');
insert into student values('103','王五','女','202001','1988-06-08');
insert into student values('104','秦明','男','202002','1978-06-09');
insert into student values('105','陈锋','女','202003','1948-02-08');

+-----+-------+------+--------+---------------------+
| sno | sname | ssex | class  | sbirthday           |
+-----+-------+------+--------+---------------------+
| 101 | 大神  || 202001 | 1988-08-08 00:00:00 |
| 102 | 李四  || 202002 | 1988-08-09 00:00:00 |
| 103 | 王五  || 202001 | 1988-06-08 00:00:00 |
| 104 | 秦明  || 202002 | 1978-06-09 00:00:00 |
| 105 | 陈锋  || 202003 | 1948-02-08 00:00:00 |
+-----+-------+------+--------+---------------------+

教师表

教师编号tno
教师名称tname
教师性别tsex
出生年月日tbrithday
职称prof
所在部门depart

create table `teacher`(
    `tno` varchar(20) primary key,
    `tname` varchar(20) not null,
    `tsex` varchar(20) not null,
    `tbrithday` datetime,
    `prof` varchar(20) not null,
    `depart` varchar(20) not null
);

insert into teacher values('201','陈老师','男','1978-02-03','副教授', '计算机系');
insert into teacher values('202','李老师','女','1968-04-08','讲师', '电子工程系');
insert into teacher values('203','王老师','男','1958-03-18','讲师', '计算机系');
insert into teacher values('204','唐老师','女','1948-05-07','助教', '电子工程系');

+-----+--------+------+---------------------+--------+------------+
| tno | tname  | tsex | tbirthday           | prof   | depart     |
+-----+--------+------+---------------------+--------+------------+
| 201 | 陈老师  || 1978-02-03 00:00:00 | 副教授  | 计算机系   |
| 202 | 李老师  || 1968-04-08 00:00:00 | 讲师    | 电子工程系 |
| 203 | 王老师  || 1958-03-18 00:00:00 | 讲师    | 计算机系   |
| 204 | 唐老师  || 1948-05-07 00:00:00 | 助教    | 电子工程系 |
+-----+--------+------+---------------------+--------+------------+

课程表

课程号cno
课程名称cname
教师编号tno

create table `course`(
    `cno` varchar(20) primary key,
    `cname` varchar(20) not null,
    `tno` varchar(20) not null,
    foreign key(tno) references teacher(tno)
);

insert into course values('301','计算机导论','201');
insert into course values('302','操作系统','204');
insert into course values('303','数字电路','202');
insert into course values('304','高等数学','203');

+-----+------------+-----+
| cno | cname      | tno |
+-----+------------+-----+
| 301 | 计算机导论  | 201 |
| 302 | 操作系统    | 204 |
| 303 | 数字电路    | 202 |
| 304 | 高等数学    | 203 |
+-----+------------+-----+

成绩表

学生学号sno
课程号cno
成绩degree

create table `score`(
    `sno` varchar(20) not null,
    `cno` varchar(20) not null,
    `degree` decimal,
    foreign key(sno) references student(sno),
    foreign key(cno) references course(cno),
    primary key(sno, cno)
);

insert into score values('101','301','98');
insert into score values('102','302','88');
insert into score values('103','303','68');
insert into score values('104','301','75');
insert into score values('101','304','100');

+-----+-----+--------+
| sno | cno | degree |
+-----+-----+--------+
| 101 | 301 |     98 |
| 101 | 304 |    100 |
| 102 | 302 |     88 |
| 103 | 303 |     68 |
| 104 | 301 |     75 |
+-----+-----+--------+

成绩等级表

下限low
上限up
评级grade

create table `grade`(
     low int(3),
     up int(3),
     grade char(1)
 )
 
insert into grade values(90,100,'A');
insert into grade values(80,89,'B');
insert into grade values(70,79,'C');
insert into grade values(60,69,'D');
insert into grade values(0,59,'E');

+------+------+-------+
| low  | up   | grade |
+------+------+-------+
|   90 |  100 | A     |
|   80 |   89 | B     |
|   70 |   79 | C     |
|   60 |   69 | D     |
|    0 |   59 | E     |
+------+------+-------+

练习:先思考,再看答案(答案在下方)

0.查询202001202002班全体同学的记录

1.查询teacher表depart列的并集

2.查询score表中成绩在6080之间的记录

3.查询score表中成绩为858688的记录

4.查询student表中202001班或性别为女的同学

5.class降序查询student表的所有记录

6.以cno升序,degree降序查询score表的所有记录

7.查询student表中202001班的学生人数

8.查询score表中的最高分的学生学号和课程号

9.查询score表中每门课的平均成绩

10.查询score表中至少有2名学生选修的课程

11.双表查询:查询所有学生的sname,cno,和degree列

12.三表联查:查询所有学生的sname,cname,和degree列

13.查询202001班学生每门课的平均分

14.查询score表中,选修301课程,并且成绩低于101号同学的301课程成绩的所有同学记录

15.查询score表中,成绩高于101号同学的301课程成绩的所有记录

16.查询和学号为101103同学同年出生的所有学生的sno,sname,sbirthday列

17.查询'陈老师'任课的学生成绩

18.查询选修课程的同学人数大于5人的教师姓名(只要老师教的课,有超过5人选修,就满足条件)
因为数据不够多,可以改成2,或者自己添加数据

19.查询最高分同学的信息

20.查询所有男教师所教的课程

21.查询选修课程编号为301且成绩至少一个高于选修302课程的同学记录

22.查询出计算机系教师所教课程的成绩表

23.查询所有老师和同学的name, sex, birthday

24.查询所有女教师和女同学的name,sex, birthday

25.查询student中不姓'李'的同学记录

26.查询student中每个学生的姓名和年龄

27.查询student中最大和最小的年龄

28.查询 和'李四' 同性别的所有同学的sname,不要李四

29.查询 和'李四' 同性别的并且同班的所有同学的sname

30.查询所有选修 计算机导论 课程的男同学的成绩表

31.双表查询:查询所有同学的sno, cno, grede列

32.四表联查:查询所有有成绩的同学的名字, 课程, 成绩等级

答案

0. 使用包含条件in
select * from student where class in (202001,202002);
+-----+-------+------+--------+---------------------+
| sno | sname | ssex | class  | sbirthday           |
+-----+-------+------+--------+---------------------+
| 101 | 大神  || 202001 | 1988-08-08 00:00:00 |
| 102 | 李四  || 202002 | 1988-08-09 00:00:00 |
| 103 | 王五  || 202001 | 1988-06-08 00:00:00 |
| 104 | 秦明  || 202002 | 1978-06-09 00:00:00 |
+-----+-------+------+--------+---------------------+

1. 使用去重distinct
select distinct depart from teacher;
+------------+
| depart     |
+------------+
| 计算机系    |
| 电子工程系  |
+------------+

2.使用条件运算符 或 范围查找
select * from score where degree between 60 and 80;
select * from score where degree > 60 and degree < 80;
+-----+-----+--------+
| sno | cno | degree |
+-----+-----+--------+
| 103 | 303 |     68 |
| 104 | 301 |     75 |
+-----+-----+--------+

3.使用包含运算符
select * from score where degree in(85, 86, 88);
+-----+-----+--------+
| sno | cno | degree |
+-----+-----+--------+
| 102 | 302 |     88 |
+-----+-----+--------+

4.使用条件运算符
select * from student where class = '202001' or ssex = '女';
+-----+-------+------+--------+---------------------+
| sno | sname | ssex | class  | sbirthday           |
+-----+-------+------+--------+---------------------+
| 101 | 大神  || 202001 | 1988-08-08 00:00:00 |
| 103 | 王五  || 202001 | 1988-06-08 00:00:00 |
| 105 | 陈锋  || 202003 | 1948-02-08 00:00:00 |
+-----+-------+------+--------+---------------------+

5.使用order by
select * from student order by class desc;
+-----+-------+------+--------+---------------------+
| sno | sname | ssex | class  | sbirthday           |
+-----+-------+------+--------+---------------------+
| 105 | 陈锋  || 202003 | 1948-02-08 00:00:00 |
| 102 | 李四  || 202002 | 1988-08-09 00:00:00 |
| 104 | 秦明  || 202002 | 1978-06-09 00:00:00 |
| 101 | 大神  || 202001 | 1988-08-08 00:00:00 |
| 103 | 王五  || 202001 | 1988-06-08 00:00:00 |
+-----+-------+------+--------+---------------------+

6.多个排序
select * from score order by cno asc, degree desc;
+-----+-----+--------+
| sno | cno | degree |
+-----+-----+--------+
| 101 | 301 |     98 |
| 104 | 301 |     75 |
| 102 | 302 |     88 |
| 103 | 303 |     68 |
| 101 | 304 |    100 |
+-----+-----+--------+

7. 使用函数
select count(*) count from student where class = '202001';
+-------+
| count |
+-------+
|     2 |
+-------+

8.使用条件子句,先找到最高分,再找学生学号和课程号
select sno, cno from score where degree=(select max(degree) from score);
+-----+-----+
| sno | cno |
+-----+-----+
| 101 | 304 |
+-----+-----+

9.以cno分组,再使用avg函数计算平均数
一门课:select cno, avg(degree) avg_degree from score where cno = '301';
每门课:select cno, avg(degree) avg_degree from score group by cno;
+-----+------------+
| cno | avg_degree |
+-----+------------+
| 301 |    86.5000 |
| 302 |    88.0000 |
| 303 |    68.0000 |
| 304 |   100.0000 |
+-----+------------+

10. 先分组,再计算筛选
select cno from score group by cno having count(cno) >= 2;
+-----+
| cno |
+-----+
| 301 |
+-----+

11. from后可以多个表,以,隔开, 或使用内联查询
select sname, cno, degree from student,score where student.sno = score.sno;
或
select sname,cno,degree from student inner join score on student.sno = score.sno;
+-------+-----+--------+
| sname | cno | degree |
+-------+-----+--------+
| 大神  | 301 |     98 |
| 大神  | 304 |    100 |
| 李四  | 302 |     88 |
| 王五  | 303 |     68 |
| 秦明  | 301 |     75 |
+-------+-----+--------+

12.三表联查
select sname, cname, degree from student, course, score where student.sno = score.sno and course.cno = score.cno;
+-------+------------+--------+
| sname | cname      | degree |
+-------+------------+--------+
| 大神  | 计算机导论   |     98 |
| 秦明  | 计算机导论   |     75 |
| 李四  | 操作系统     |     88 |
| 王五  | 数字电路     |     68 |
| 大神  | 高等数学     |    100 |
+-------+------------+--------+

进阶:按sname升序和degree降序,如果需要limit还可以在后面加
select sname, cname, degree from student, course, score where student.sno = score.sno and course.cno = score.cno order by sname asc, degree desc;
+-------+------------+--------+
| sname | cname      | degree |
+-------+------------+--------+
| 大神  | 高等数学    |    100 |
| 大神  | 计算机导论  |     98 |
| 李四  | 操作系统    |     88 |
| 王五  | 数字电路    |     68 |
| 秦明  | 计算机导论  |     75 |
+-------+------------+--------+

13. 原则:复杂的查询,先分段进行
先获取202001班的所有学生学号:select sno from student where class = '202001';
再获取这些学生的所有课程:select * from score where sno in (select sno from student where class='202001');
最后以课程分组和计算平均分:select cno, avg(degree) avg_drgree from score where sno in (select sno from student where class='202001') group by cno;
+-----+------------+
| cno | avg_drgree |
+-----+------------+
| 301 |    98.0000 |
| 304 |   100.0000 |
| 303 |    68.0000 |
+-----+------------+

14. 使用条件子句
先查询101号同学的301号课程成绩:select degree from score where sno = '101' and cno = '301';
再获取301号课程的其他同学:select * from score where cno = '301' and degree < (select degree from score where sno='101' and cno='301');
+-----+-----+--------+
| sno | cno | degree |
+-----+-----+--------+
| 104 | 301 |     75 |
+-----+-----+--------+

15. 使用条件子句
select * from score where degree > (select degree from score where sno = '101' and cno = '301');
+-----+-----+--------+
| sno | cno | degree |
+-----+-----+--------+
| 101 | 304 |    100 |
+-----+-----+--------+

16. 使用year()函数
先获取101103同学的日期:select year(sbirthday) from student where sno in (101,103);
再获取其他学生:select * from student where year(sbirthday) in (select year(sbirthday) from student where sno in (101,103));
+-----+-------+------+--------+---------------------+
| sno | sname | ssex | class  | sbirthday           |
+-----+-------+------+--------+---------------------+
| 101 | 大神  || 202001 | 1988-08-08 00:00:00 |
| 102 | 李四  || 202002 | 1988-08-09 00:00:00 |
| 103 | 王五  || 202001 | 1988-06-08 00:00:00 |
+-----+-------+------+--------+---------------------+

17. 多层嵌套查询
分析:成绩需要在成绩表里取,但成绩表里不知道陈老师教的是什么课,需要去课程表里取,课程表里不知道陈老师的编号是多少,需要去老师表里取。
先在teacher获取陈老师的编号:select tno from teacher where tname = '陈老师';
再到course获取陈老师的课程编号:select cno from course where tno = (select tno from teacher where tname = '陈老师');
最后根据课程编号获取学生成绩:select * from score where cno = (select cno from course where tno = (select tno from teacher where tname = '陈老师'));
+-----+-----+--------+
| sno | cno | degree |
+-----+-----+--------+
| 101 | 301 |     98 |
| 104 | 301 |     75 |
+-----+-----+--------+

18. 多层嵌套查询
先获取课程编号,分组,筛选,计算总数:select cno from score group by cno having count(*) >= 2;
再获取老师编号: select tno from course where cno = (select cno from score group by cno having count(*) >= 2);
最后获取老师名字:select * from teacher where tno = (select tno from course where cno=(select cno from score group by cno having count(*) >= 2));
+-----+--------+------+---------------------+--------+----------+
| tno | tname  | tsex | tbirthday           | prof   | depart   |
+-----+--------+------+---------------------+--------+----------+
| 201 | 陈老师  || 1978-02-03 00:00:00 | 副教授  | 计算机系  |
+-----+--------+------+---------------------+--------+----------+

19. 多层嵌套查询
select * from student where sno = (select sno from score where degree in (select max(degree) from score));
+-----+-------+------+--------+---------------------+
| sno | sname | ssex | class  | sbirthday           |
+-----+-------+------+--------+---------------------+
| 101 | 大神  || 202001 | 1988-08-08 00:00:00 |
+-----+-------+------+--------+---------------------+

20.
select tno from teacher where tsex = '男';
select * from course where tno in (select tno from teacher where tsex = '男');
+-----+------------+-----+
| cno | cname      | tno |
+-----+------------+-----+
| 301 | 计算机导论  | 201 |
| 304 | 高等数学    | 203 |
+-----+------------+-----+

21. 使用any:任何一个
select * from score where cno = '301';
select * from score where cno = '302' and degree > any(select degree from score where cno='301');
+-----+-----+--------+
| sno | cno | degree |
+-----+-----+--------+
| 102 | 302 |     88 |
+-----+-----+--------+

22.稍后补上

23. 双表联查:使用as 和 union联表查询
select tname as name, tsex as sex, tbirthday as birthday from teacher union select sname, ssex, sbirthday from student;
+--------+-----+---------------------+
| name   | sex | birthday            |
+--------+-----+---------------------+
| 陈老师 || 1978-02-03 00:00:00 |
| 李老师 || 1968-04-08 00:00:00 |
| 王老师 || 1958-03-18 00:00:00 |
| 唐老师 || 1948-05-07 00:00:00 |
| 大神   || 1988-08-08 00:00:00 |
| 李四   || 1988-08-09 00:00:00 |
| 王五   || 1988-06-08 00:00:00 |
| 秦明   || 1978-06-09 00:00:00 |
| 陈锋   || 1948-02-08 00:00:00 |
+--------+-----+---------------------+

24. 双表联查:union联表查询 + where
select tname as name, tsex as sex, tbirthday as birthday from teacher where tsex = '女' union select sname, ssex, sbirthday from student where ssex = '女';
+--------+-----+---------------------+
| name   | sex | birthday            |
+--------+-----+---------------------+
| 李老师 || 1968-04-08 00:00:00 |
| 唐老师 || 1948-05-07 00:00:00 |
| 王五   || 1988-06-08 00:00:00 |
| 陈锋   || 1948-02-08 00:00:00 |
+--------+-----+---------------------+

25.使用模糊查询like
select * from student where sname not like '李%';
+-----+-------+------+--------+---------------------+
| sno | sname | ssex | class  | sbirthday           |
+-----+-------+------+--------+---------------------+
| 101 | 大神  || 202001 | 1988-08-08 00:00:00 |
| 103 | 王五  || 202001 | 1988-06-08 00:00:00 |
| 104 | 秦明  || 202002 | 1978-06-09 00:00:00 |
| 105 | 陈锋  || 202003 | 1948-02-08 00:00:00 |
+-----+-------+------+--------+---------------------+

26.使用now() + year()
年龄:当前年 - 出生年
select year(sbirthday) from student;
select sname, year(now())-year(sbirthday) as 'age' from student;
+-------+------+
| sname | age  |
+-------+------+
| 大神  |   33 |
| 李四  |   33 |
| 王五  |   33 |
| 秦明  |   43 |
| 陈锋  |   73 |
+-------+------+

27. min/max + year + now
注意:时间越多,年龄越小
select year(now())-year(min(sbirthday)) as max_age, year(now())-year(max(sbirthday)) as min_age from student;
+---------+---------+
| max_age | min_age |
+---------+---------+
|      73 |      33 |
+---------+---------+

29. 条件拼接
select sname from student where ssex = (select ssex from student where sname='李四') and sname != '李四';
+-------+
| sname |
+-------+
| 大神  |
| 秦明  |
+-------+

30. 条件拼接
select sname from student where ssex = (select ssex from student where sname='李四') and sname != '李四' and class = (select class from student where sname = '李四');
+-------+
| sname |
+-------+
| 秦明  |
+-------+

30.
select * from student where ssex = '男';
select cno from course where cname = '计算机导论';
select * from score where cno = (select cno from course where cname = '计算机导论') and sno in (select sno from student where ssex = '男');
+-----+-----+--------+
| sno | cno | degree |
+-----+-----+--------+
| 101 | 301 |     98 |
| 104 | 301 |     75 |
+-----+-----+--------+

31.双表查询
select sno, cno, grade from score, grade where degree between low and up;
+-----+-----+-------+
| sno | cno | grade |
+-----+-----+-------+
| 101 | 301 | A     |
| 101 | 304 | A     |
| 102 | 302 | B     |
| 104 | 301 | C     |
| 103 | 303 | D     |
+-----+-----+-------+

32. 四表联查:学生表,成绩表,课程表,成绩等级表,多表,多条件
全部字段:select * from student as stu, score as sco, course as cou, grade as gra where sco.cno = cou.cno and stu.sno = sco.sno and sco.degree between low and up;
要的字段:select stu.sno, sname, cname, grade from student as stu, score as sco, course as cou, grade as gra where sco.cno = cou.cno and stu.sno = sco.sno and sco.degree between low and up;
+-----+-------+------------+-------+
| sno | sname | cname      | grade |
+-----+-------+------------+-------+
| 101 | 大神  | 计算机导论   | A     |
| 101 | 大神  | 高等数学     | A     |
| 102 | 李四  | 操作系统     | B     |
| 103 | 王五  | 数字电路     | D     |
| 104 | 秦明  | 计算机导论   | C     |
+-----+-------+------------+-------+

后补

暂无

学习更多

mysql学习导图

你可能感兴趣的:(mysql,mysql)