mysql中经典50道题目
2023-03-15 23:29:33 时间
1、四表之间的关联关系及字段说明
2、建表语句和插入数据
1)student表
-- student表
create table student(
sid varchar(20),
sname varchar(20),
sage datetime,
ssex varchar(10)
)charset=utf8;
-- student表中插入数据
insert into student values
('01' , '赵雷' , '1990-01-01' , '男'),
('02' , '钱电' , '1990-12-21' , '男'),
('03' , '孙风' , '1990-12-20' , '男'),
('04' , '李云' , '1990-12-06' , '男'),
('05' , '周梅' , '1991-12-01' , '女'),
('06' , '吴兰' , '1992-01-01' , '女'),
('07' , '郑竹' , '1989-01-01' , '女'),
('09' , '张三' , '2017-12-20' , '女'),
('10' , '李四' , '2017-12-25' , '女'),
('11' , '李四' , '2012-06-06' , '女'),
('12' , '赵六' , '2013-06-13' , '女'),
('13' , '孙七' , '2014-06-01' , '女');
2)score表(sc表)
-- score表
create table sc(
sid varchar(20),
cid varchar(20),
score int
)charset=utf8;
-- score表中插入数据
insert into sc values
('01' , '01' , 80),
('01' , '02' , 90),
('01' , '03' , 99),
('02' , '01' , 70),
('02' , '02' , 60),
('02' , '03' , 80),
('03' , '01' , 80),
('03' , '02' , 80),
('03' , '03' , 80),
('04' , '01' , 50),
('04' , '02' , 30),
('04' , '03' , 20),
('05' , '01' , 76),
('05' , '02' , 87),
('06' , '01' , 31),
('06' , '03' , 34),
('07' , '02' , 89),
('07' , '03' , 98);
3)course表
-- course表
create table course(
cid varchar(20),
cname varchar(20),
tid varchar(20)
)charset=utf8;
-- course表中插入数据
insert into course values
('01' , '语文' , '02'),
('02' , '数学' , '01'),
('03' , '英语' , '03');
4)teacher表
-- teacher表
create table teacher(
tid varchar(20),
tname varchar(20)
)charset=utf8;
-- teacher表中插入数据
insert into teacher values
('01' , '张三'),
('02' , '李四'),
('03' , '王五');
3、50道题目
1)查询"01"课程比"02"课程成绩高的学生的信息及课程分数。
select
s.*,
a.score score01,
b.score score02
from
student s
join
sc a on s.sid=a.sid and a.cid="01"
join
sc b on s.sid=b.sid and b.cid="02"
where
a.score > b.score;
2)查询"01"课程比"02"课程成绩低的学生的信息及课程分数。
select
s.*,
a.score score01,
b.score score02
from
student s
join
sc a on s.sid=a.sid and a.cid="01"
join
sc b on s.sid=b.sid and b.cid="02"
where
a.score < b.score;
3)查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩。
select
s.sid,
s.sname,
avg(score) avg_score
from
student s
left join
sc on s.sid= sc.sid
group by
s.sid,s.sname
having
avg_score > 60;
4)查询平均成绩小于60分的同学的学生编号和学生姓名和平均成绩。
select
s.sid,
s.sname,
avg(score) avg_score
from
student s
left join
sc on s.sid= sc.sid
group by
s.sid,s.sname
having
avg_score < 60;
5)查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩。
select
s.sid,
s.sname,
count(cid) counts,
sum(score) sum_score
from
student s
left join
sc on s.sid= sc.sid
group by
s.sid,s.sname;
6)查询"李"姓老师的数量。
select
count(*) counts
from
teacher
where
tname like "李%";
7)查询学过"张三"老师授课的同学的信息。
select
s.*
from
student s
join
sc on s.sid=sc.sid
where
sc.cid=(select cid from course where tid=(select tid from teacher where tname="张三"));
8)查询没学过"张三"老师授课的同学的信息。
select student.*
from student
where sid not in
(
select
s.sid
from
student s
join
sc on s.sid=sc.sid
where
sc.cid=(select cid from course where tid=(select tid from teacher where tname="张三"))
);
9)查询学过编号为"01"并且也学过编号为"02"的课程的同学的信息。
select
s.*
from
student s
join
sc a on s.sid=a.sid and a.cid="01"
join
sc b on s.sid=b.sid and b.cid="02";
10)查询学过编号为"01"但是没有学过编号为"02"的课程的同学的信息。(这一题要好好理解一下)
select
s.*
from
student s
left join
sc a on s.sid = a.sid and a.cid = '01'
left join
sc b on s.sid = b.sid and b.cid = '02'
where
a.sid is not null and b.sid is null;
11)查询没有学全所有课程的同学的信息。
select
c.*
from (
select s.sid sid,count(cid) counts
from student s
left join sc a on s.sid=a.sid
group by s.sid
having counts<(select count(*) from course)
)b
join
student c
on
b.sid=c.sid;
12)查询至少有一门课与学号为"01"的同学所学相同的同学的信息。
select
distinct s.*
from
student s
join
sc on s.sid=sc.sid
where
sc.cid in (select cid from sc where sid="01");
13)查询和"01"号的同学学习的课程完全相同的其他同学的信息。(这一题有点难)
14)查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩。
select
s.sid,s.sname,count(cid) counts,avg(score) avg_score
from
student s
join
sc on s.sid=sc.sid
where
sc.score < 60
group by
s.sid,s.sname
having
counts >=2;
15)检索"01"课程分数小于60,按分数降序排列的学生信息。
select
s.*
from
student s
join
sc on s.sid=sc.sid
where
sc.cid="01" and sc.score<60
order by
sc.score desc;
16)按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩。
select
a.sname,b.score,c.avg_score avg_score
from
student a
left join
sc b on a.sid=b.sid
left join
(
select s.sid sid,avg(score) avg_score
from student s
left join sc on s.sid=sc.sid
group by sid
)c
on a.sid=c.sid
order by
avg_score desc;
17)查询各科成绩最高分、最低分和平均分。
- 以如下形式显示:
- 课程id,课程name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率
- 及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90
select
cid,
max(score) 最高分,
min(score) 最低分,
avg(score) 平均分,
sum(case when score>=60 then 1 else 0 end)/count(*) 及格率,
sum(case when score>=70 and score<80 then 1 else 0 end)/count(*) 中等率,
sum(case when score>=80 and score<90 then 1 else 0 end)/count(*) 优良率,
sum(case when score>=90 then 1 else 0 end)/count(*) 优秀率
from
sc
group by
cid;
18)按各科成绩进行排序,并显示排名。(有一点难度)
19)查询学生的总成绩并进行排名。
-- 设置一个全局变量;
set @num=0;
select
a.sname,
a.sum_score,
@num:=@num+1 as ranks
from
(
select s.sname sname,sum(sc.score) sum_score
from student s
join sc
on s.sid=sc.sid
group by s.sid,s.sname
order by sum_score desc
)a;
20)查询不同老师所教不同课程平均分从高到低显示。
select
c.tid,
avg(sc.score) avg_score
from
sc
join
course c
on
sc.cid=c.cid
group by
c.tid;
21)查询1990年1月份出生的学生名单。
select
*
from
student
where
year(sage)="1990" and month(sage)="1";
22)统计各科成绩各分数段人数。
- 课程编号,课程名称,[100-85],[85-70],[70-60],[0-60]及所占百分比
select
sc.cid,
c.cname,
sum(case when score>=0 and score<60 then 1 else 0 end) '[0-60]',
sum(case when score>=60 and score<70 then 1 else 0 end) '[60-70]',
sum(case when score>=70 and score<85 then 1 else 0 end) '[70-85]',
sum(case when score>=85 and score<=100 then 1 else 0 end) '[85-100]',
sum(case when score>=0 and score<60 then 1 else 0 end)/count(*) '[0-60]占比',
sum(case when score>=60 and score<70 then 1 else 0 end)/count(*) '[60-70]占比',
sum(case when score>=70 and score<85 then 1 else 0 end)/count(*) '[70-85]占比',
sum(case when score>=85 and score<=100 then 1 else 0 end)/count(*) '[85-100]占比'
from
sc
join
course c on sc.cid=c.cid
group by
sc.cid,c.cname;
23)查询学生平均成绩及其名次。
set @num=0;
select
a.sid,
a.avg_score,
@num:=@num+1 rank
from
(
select sid,avg(score) avg_score
from sc
group by sid
order by avg_score desc
)a;
24)查询各科成绩前三名的记录。
select
a.cid,
a.score
from
sc a
where
(select count(*) from sc b where a.cid=b.cid and a.score<b.score)<3
order by
a.cid,a.score desc;
25)查询每门课程被选修的学生数。
select
cid,
count(*) counts
from
sc
group by
cid;
26)查询出只有两门课程的全部学生的学号和姓名。
select
s.sid,
s.sname
from
student s
join
sc
on
s.sid=sc.sid
group by
s.sid,s.sname
having
count(*)=2;
27)查询男生、女生人数。
select
ssex,
count(*) counts
from
student
group by
ssex;
28)查询名字中含有"风"字的学生信息。
select
*
from
student
where
sname like "%风%";
29)查询同名同性学生名单,并统计同名人数。
select
sname,
ssex,
count(*) counts
from
student
group by
sname,ssex
having
counts>=2;
30)查询1990年出生的学生名单。
select
*
from
student
where
year(sage)="1990";
31)查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号。
select
cid,
avg(score) avg_score
from
sc
group by
cid
order by
avg_score desc,cid asc;
32)查询平均成绩大于等于85的所有学生的学号、姓名和平均成绩 。
select
s.sid,
s.sname,
avg(score) avg_score
from
student s
join
sc
on
s.sid=sc.sid
group by
s.sid,s.sname
having
avg_score>=85;
33)查询课程名称为"数学",且分数低于60的学生姓名和分数。
select
s.sname,
sc.score
from
student s
join
sc
on
s.sid=sc.sid
join
course c
on
sc.cid=c.cid
where
c.cname="数学" and sc.score<60;
34)查询所有学生的课程及分数情况。
select
*
from
student s
left join
sc
on
s.sid=sc.sid
left join
course c
on
sc.cid=c.cid;
35)查询任何一门课程成绩在70分以上的姓名、课程名称和分数。
select
s.sname,
c.cname,
sc.score
from
student s
left join
sc on s.sid = sc.sid
left join
course c on sc.cid = c.cid
where
score > 70;
36)查询不及格的课程名称。
select
distinct c.cname
from
sc
join
course c
on
sc.cid=c.cid
where
sc.score<60;
37)查询课程编号为01且课程成绩在80分以上(包含80分)的学生的学号和姓名。
select
s.sid,
s.sname
from
student s
join
sc
on
s.sid=sc.sid
where
sc.cid="01" and sc.score>=80;
38)求每门课程的学生人数 。
select
cid,
count(*) counts
from
sc
group by
cid;
39)查询选修"张三"老师所授课程的学生中,成绩最高的学生信息及其成绩。
select
s.*,
sc.score
from
student s
join
sc on s.sid=sc.sid
join
course c on c.cid=c.cid
join
teacher t on c.tid=t.tid
where
t.tname="张三"
order by
sc.score desc
limit 1;
40)查询每个学生中,不同课程但成绩相同的学生的学生编号、课程编号、学生成绩。
select
a.sid,a.cid,a.score,b.cid,b.score
from
sc a
join
sc b
on
a.sid=b.sid
where
a.cid != b.cid and a.score = b.score;
41)查询每门功课成绩最好的前两名。
select
a.cid,
a.score
from
sc a
where
(select count(*) from sc b where a.cid=b.cid and a.score<b.score)<2
order by
a.cid,a.score desc;
42)查询选修了全部课程的学生信息。
select
s.*
from
student s
join
(
select sid
from sc
group by sid
having count(*)=3
) a
on
s.sid=a.sid;
43)查询各学生的年龄。
select
sname,
(year(now())-year(sage)) age
from
student;
44)查询本周过生日的学生。
-- 本周实际为周4,但是返回结果是3,但是不影响。
select weekday(now());
-- 返回结果是2019-12-31 23:59:59。
select date_add('1999-12-31 23:59:59',interval (year(now())-year('1999-12-31 23:59:59')) year);
-- 返回结果是本周周一的日期:2019-12-09 10:04:02
select date_add(now(),interval -weekday(now()) day);
-- 返回结果是本周周日的日期:2019-12-15 10:04:37
select date_add(now(),interval 6-weekday(now()) day);
-- 完整代码如下:
select
sname,sage
from
student
where
date_add(sage,interval (year(now())-year(sage)) year)
between
date_add(now(),interval -weekday(now()) day)
and
date_add(now(),interval 6-weekday(now()) day);
45)查询下周过生日的学生。
select
sname,sage
from
student
where
date_add(sage,interval (year(now())-year(sage)) year)
between
date_add(now(),interval 7-weekday(now()) day)
and
date_add(now(),interval 7-weekday(now())+6 day);
46)查询本月过生日的学生。
select
sname
from
student
where
month(now())=month(sage);
47)查询下月过生日的学生。
-- 这里不能直接使用month(now)+1表示下一个月,当月份为12的时候,加1就表示13了;
--因此,使用date_add()函数,可以在原来日期基础上,增加年/月/日/时/分;
select
sname
from
student
where
month(date_add(now(),interval 1 month))=month(sage);
相关文章
- 系统性能排查方略及大型银行MySQL性能管控
- 为什么线程有时会在 MySQL 中保持“killed”状态?
- 外包做的系统宕机了,逼得我重新设计一套MySQL数据库架构
- 从零开始实现一个MyBatis加解密插件
- 聊聊PG数据库的防误删除问题
- 温故知新--G行EverDB自动化混沌测试之路
- 将数据从 MySQL 导出到 SQL Server
- 「一招制敌」老板再也不用为“搜索不到数据”而操心了
- 数据库开发应知应会之笛卡尔积
- Where Field in(...) 是怎么执行的?
- 小白入门:什么是CURD?
- 不懂就问:SQL 语句中 where 条件后 写上1=1 是什么意思
- ElasticSearch这些坑记得避开
- HarmonyOS 分布式之聊天室应用
- 银行业业务场景与数据库选型分析
- 齐活了,Grafana 发布大规模持续性能分析开源数据库 - Phlare
- MySQL窗口函数优秀实践,你学会了吗?
- 查询语言的那些事儿:程序员应该知道的SQL、HQL、JPQL和CQL
- Flink SQL通过Hudi HMS Catalog读写Hudi并同步Hive表
- MySQL 执行计划中的rows到底是什么,你真的了解过?