当前位置: 首页 > news >正文

MySQL五十题

1. 查询"01"课程比"02"课程成绩高的学生信息及课程分数

SELECT
	a.s_id,
	student.s_name,
	a.s_score '01',
	b.s_score '02' 
FROM
	( SELECT s_id, c_id, s_score FROM score WHERE c_id = '01' ) AS a
	INNER JOIN ( SELECT s_id, c_id, s_score FROM score WHERE c_id = '02' ) AS b ON a.s_id = b.s_id
	INNER JOIN student ON student.s_id = a.s_id 
WHERE
	a.s_score > b.s_score

想获得     

先获得    在成绩表里筛出    a表:课程01     , b表同理

然后通过s_id关联,就可以获得学生的两门成绩

筛选课程01>课程02

关联学生表补充学生信息

2. 查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩

SELECT student.s_id,student.s_name,round(avg,2) as avg
from student
INNER JOIN
(
SELECT s_id,avg(s_score) as avg
FROM score
GROUP BY s_id HAVING avg(s_score)>=60
) t
on student.s_id=t.s_id

round(avg(s_score),2) 表示对 avg(s_score) 进行四舍五入到小数点后两位

用分数表先根据id分组查出每个学生的平均成绩,然后内连接学生表查信息

注意给avg(s_score)起个别名,不然第一行直接写的话会说找不到s_score

3. 查询所有同学的学编号、学生姓名、选课总数、所有课程的总成绩

SELECT
	student.s_id,student.s_name,count( score.s_id ),
	sum(CASE WHEN score.s_score IS NULL THEN 0 ELSE score.s_score END) 
FROM student
	LEFT JOIN score ON score.s_id = student.s_id 
GROUP BY
	s_id,student.s_name

学生有可能没有成绩,所以不要先查子表再套学生表了,直接拉大通铺后再分组

规范:如果有group by,查询内容就能写gruop by里有的信息和计算函数,根据id和name的分组结果是一样的,所以都写,这样就可以在第二行写上去了

然后学会使用case when来规避null

4. 查询姓“李”的老师的数量

SELECT count(teacher.t_name)
from teacher
where teacher.t_name like '李%'

若需要对名字去重,则为 count(distinct teacher.t_name),但distinct效率低,优化时可能不会使用

*5.查询没学过"张三"老师讲授的任何一门课程的学生姓名

SELECT s_name from student where s_id not in(
SELECT s_id from score where c_id=(
SELECT c_id from course where t_id=(
SELECT t_id from teacher where t_name = '张三')))
SELECT s_id,s_name from student
WHERE s_id not in(
SELECT s_id from score
INNER JOIN course on score.c_id=course.c_id
INNER JOIN teacher on teacher.t_id=course.t_id
WHERE teacher.t_name='张三')

做一个这样的大表,筛选教师姓名为张三的

6. 查询学过“张三”老师授课的同学的信息

上题的 not in 改为 in

*7.查询同时存在"01"课程和"02"课程的学生id和姓名

SELECT student.s_id,student.s_name from student where s_id in(
SELECT a.s_id from
(SELECT s_id from score WHERE c_id != '01') a
INNER JOIN
(SELECT s_id from score WHERE c_id = '02') b
on a.s_id=b.s_id)

9.查询所有课程小于60分的学生学号姓名

SELECT a.s_id from
(SELECT s_id,count(s_id) as c1 from score WHERE s_score<60 GROUP BY s_id) as a
-- 每个同学课程小于60的课程数
INNER JOIN
(SELECT s_id,count(c_id) as c2 from score GROUP BY s_id) as b -- 每个同学共学了几门课
on a.s_id=b.s_id
WHERE a.c1=b.c2

10.查询没有学全所有课程的同学的信息

SELECT student.* from student where student.s_id in(
SELECT student.s_id from student LEFT JOIN score on student.s_id=score.s_id 
GROUP BY student.s_id HAVING count(c_id)<(SELECT count(c_id) from course)
)

不可以把两个表内连接!一定左外连接!不然会漏掉啥课都没选的学生!!

SELECT student.* from student where student.s_id not in(
SELECT s_id from score 
GROUP BY s_id HAVING count(s_id)=(SELECT count(c_id) from course)
)

法二:先查课程全选的学生,然后排除掉

11.查询至少有一门课与学号为01的同学所学相同的同学的信息

SELECT DISTINCT student.s_id,s_name from student 
LEFT JOIN score on student.s_id=score.s_id where c_id 
in (SELECT c_id from score where s_id='01') and student.s_id!='01'

*12.查询和"01"号的同学学习的课程完全相同的其他同学的信息

SELECT * from student where s_id in( -- 一定在第一个表里

SELECT s_id from score WHERE s_id!='01'
GROUP BY s_id                          -- 与01同学的课程数一样的
HAVING count(c_id)=(SELECT count(c_id) from score WHERE s_id='01'))

and s_id not in( -- 不能在这个表里

SELECT DISTINCT s_id from score WHERE c_id not in -- 哪些同学修了别的课
(SELECT c_id from score where s_id='01')) -- 01同学修了哪些课

01同学选了1,2,3三门课

表一:选出所学的课不在(1,2,3)的同学  排除

表二:剩下的同学肯定选了(1,2,3)里的课,选出所学课程数是否等于3

*15. 查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩

SELECT student.s_id,s_name,avg(s_score) from student
INNER JOIN score on student.s_id=score.s_id -- 大通铺
where student.s_id in(-- 两门及以上不及格的同学
SELECT s_id from score WHERE s_score<60 GROUP BY s_id HAVING count(c_id)>=2)
GROUP BY s_id,s_name

先拉大通铺,最后gruop by

16. 查询"01"课程分数小于60,按分数降序排列的学生信息

SELECT student.*,c_id,s_score from student INNER JOIN score on student.s_id=score.s_id
where c_id='01' and s_score<60
ORDER BY s_score desc

先拉大通铺

*17. 按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩

SELECT student.s_id,s_name,
max(case when c_id='01' then s_score else null end) '01',
max(case when c_id='02' then s_score else null end) '02',
max(case when c_id='03' then s_score else null end) '03',
avg(s_score)
from student
LEFT JOIN score on student.s_id=score.s_id 
GROUP BY student.s_id,s_name
ORDER BY avg(s_score) DESC

*18.查询各科成绩最高分,最低分,平均分,及格率,中等率,优良率,优秀率

课程ID,课程name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率
     及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90

SELECT score.c_id,c_name,max(s_score),min(s_score),avg(s_score),
concat(round(sum(case when s_score>=60 then 1 else 0 end)/count(s_id)*100,2),'%') 及格率,
concat(round(sum(case when s_score BETWEEN 70 and 80 then 1 else 0 end)/count(s_id)*100,2),'%') 中等率,
concat(round(sum(case when s_score BETWEEN 80 and 90 then 1 else 0 end)/count(s_id)*100,2),'%') 优良率,
concat(round(sum(case when s_score>=90 then 1 else 0 end)/count(*)*100,2),'%') 优秀率
from score INNER JOIN course on course.c_id=score.c_id
GROUP BY c_id,c_name

19. 按各科平均成绩进行排序,并显示排名,Score重复时保留名次空缺

SELECT dense_rank() over(partition by score.c_id ORDER BY s_score DESC) as ranked,
score.c_id,c_name,student.s_id,s_name,s_score from score
INNER JOIN course on course.c_id=score.c_id
INNER JOIN student on student.s_id=score.s_id

dense_rank()  over(partition by score.c_id ORDER BY s_score DESC)

根据c_id分组,组内排名,根据score降序排名

20. 查询学生的总成绩,并进行排名,总分重复时不保留名次空缺

SELECT rank() over(ORDER BY sum(s_score) desc),s_id,sum(s_score)
from score GROUP BY s_id

21、查询不同老师所教不同课程平均分从高到低显示

SELECT teacher.t_id,t_name, score.c_id,c_name,avg(s_score) avg from score 
INNER JOIN course on score.c_id=course.c_id 
INNER JOIN teacher on teacher.t_id=course.t_id
GROUP BY score.c_id ,c_name,teacher.t_id,t_name
ORDER BY avg desc

*22、查询所有课程的成绩第2名到第3名的学生信息及该课程成绩

SELECT * from(
SELECT student.s_id,s_name,c_id,s_score,
row_number () over(partition by c_id ORDER BY s_score desc) m
from score INNER JOIN student on score.s_id=student.s_id
) a where a.m in (2,3)

您试图在 WHERE 子句中直接使用窗口函数 ROW_NUMBER() 生成的列 ran。在大多数 SQL 数据库系统中,窗口函数的结果不能直接在 WHERE 子句中使用,因为 WHERE 子句在窗口函数之前执行

所以要最外面套一个 SELECT * from(

*23. 统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[60-0]及所占百分比

SELECT course.c_id,c_name,
count(case when s_score<=100 and s_score>85 then 88888 else null end) '[100,85)',
sum(case when s_score<=85 and s_score>70 then 1 else 0 end) '[85,70)',
sum(case when s_score<=70 and s_score>60 then 1 else 0 end) '[70,60)',
sum(case when s_score<60 then 1 else 0 end) '(<60)'
from course INNER JOIN score on score.c_id=course.c_id
GROUP BY c_id,c_name

24.查询学生平均成绩及其名次

SELECT s_id,avg(s_score),ROW_NUMBER() over(ORDER BY avg(s_score) desc)
from score GROUP BY s_id

25. 查询各科成绩前三名的记录

26. 查询每门课程被选修的学生数

SELECT score.c_id,c_name,count(score.c_id) 
from score INNER JOIN course on score.c_id=course.c_id
GROUP BY score.c_id,c_name

e27. 查询只选修两门课程的学生学号和姓名

SELECT score.s_id,s_name from score 
INNER JOIN student on score.s_id=student.s_id
GROUP BY score.s_id,s_name HAVING count(score.s_id)=2

28. 查询男生女生人数

SELECT s_sex,count(s_id) from student GROUP BY s_sex
SELECT
count(case when s_sex='男' then 999 else null end) '男生人数',
sum(case when s_sex='女'   then 1   else 0    end) '女生人数'
from  student

e29. 查询名字中含有“风”字的学生信息

SELECT * from student where s_name like '%风%'

31. 查询1990年出生的学生名单

SELECT * from student WHERE year(s_birth)=1990

e32. 查询平均成绩大于等于85的所有学生的学号,姓名和平均成绩

SELECT student.s_id,s_name,avg(s_score) from student
INNER JOIN score on student.s_id=score.s_id
GROUP BY student.s_id,s_name HAVING avg(s_score)>=85

33. 查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列

SELECT score.c_id,c_name,avg(s_score) from score 
INNER JOIN course on course.c_id=score.c_id
GROUP BY score.c_id,c_name
ORDER BY avg(s_score) desc,c_id asc

34. 查询课程名称为「数学」,且分数低于 60 的学生姓名和分数

SELECT s_name,s_score from score
INNER JOIN course on score.c_id=course.c_id
INNER JOIN student on score.s_id=student.s_id
where c_name='数学' and s_score<60

*35. 查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况)

SELECT student.s_id,s_name,
max(case when c_name='语文' then score.s_score else null end) '语文',
max(case when c_name='数学' then score.s_score else null end) '数学',
max(case when c_name='英语' then score.s_score else null end) '英语'
from student 
left JOIN score on student.s_id=score.s_id
left JOIN course on course.c_id=score.c_id
GROUP BY student.s_id,s_name

如果gruop by后之间查成绩,case when c_name=数学后给数学成绩赋值,但只会返回本列第一个

e36. 查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数

SELECT s_name,c_name,s_score from student
INNER JOIN score on score.s_id=student.s_id
INNER JOIN course on course.c_id=score.c_id
where s_score>=70

e37. 查询不及格的课程并按课程号从大到小排列

SELECT student.s_id,s_name,course.c_id,c_name,s_score from score 
INNER JOIN course on score.c_id=course.c_id
INNER JOIN student on student.s_id=score.s_id
where s_score<60 ORDER BY c_id desc

e38. 查询课程编号为 03 且课程成绩在 80 分以上的学生的学号和姓名

SELECT student.s_id,s_name,c_id,s_score from score 
INNER JOIN student on student.s_id=score.s_id
where c_id='03' and s_score>80

e39. 求每门课程的学生人数

SELECT score.c_id,c_name,count(score.c_id) from score 
right JOIN course on score.c_id=course.c_id
GROUP BY score.c_id,c_name

40.查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩

SELECT s_name,s_score from student
INNER JOIN score on student.s_id=score.s_id
INNER JOIN course on course.c_id=score.c_id
INNER JOIN teacher on course.t_id=teacher.t_id
where t_name='张三' 
ORDER BY s_score DESC LIMIT 0,1

*41. 查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩

SELECT * from score WHERE s_score in(
SELECT s_score from score GROUP BY s_score HAVING count(s_score)>1)

43. 统计每门课程的学生选修人数(超过 5 门的课程才统计)。输出课程号和选修人数,按人数降序、课程升序排列

SELECT c_id,count(DISTINCT s_id) FROM score GROUP BY c_id HAVING count(c_id)>5
ORDER BY count(c_id) desc,c_id asc

count(DISTINCT s_id) 是为了防止有人重修

e44. 检索至少选修两门课程的学生学号

SELECT s_id from score GROUP BY s_id HAVING count(s_id)>=2

45. 查询选修了全部课程的学生信息

SELECT s_id from score GROUP BY s_id HAVING count(s_id)=
(SELECT count(c_id) from course)

46. 查询各学生的年龄,只按年份来算

SELECT s_id,s_birth,
floor(datediff(CURDATE(),s_birth)/365)
from student;

48. 查询下周过生日的学生

SELECT * from student where 
week(concat(year(curdate()),substring(s_birth,6,5)),1)=week(curdate(),1)+1

49. 查询本月过生日的学生

SELECT * from student where month(s_birth)=month(current_date())

50. 查询下个月过生日的学生

SELECT * from student where 
case when month(curdate()=12) then month(s_birth)=1
else month(s_birth)=month(curdate())+1 end

小心下个月是13月

29. 查询同名同性学生名单,并统计同名人数


46. 查询各学生的年龄,按照出生日期来算,当前月份 < 出生年月的月日则,年龄减一

相关文章:

  • C 语言测验
  • 《Linux运维总结:基于银河麒麟V10+ARM64架构CPU二进制部署单实例rabbitmq3.10.25》
  • windows使用nvm管理node版本
  • 3. 费曼学习法?
  • 性能比拼: Pingora vs Nginx (My NEW Favorite Proxy)
  • 蓝桥杯 刷题对应的题解
  • stm32 can 遥控帧的问题
  • 全局曝光与卷帘曝光
  • 海康摄像头通过Web插件进行预览播放和控制
  • IP 地址规划中的子网划分:/18 网络容纳 64 个 C 段(/24)的原理与应用解析
  • SpringCould微服务架构之Docker(8)
  • 面基:Java项目中跟钉钉接口对接,如何确保数据传输安全性和稳定性
  • 深度学习 Deep Learning 第11章 实用方法论
  • 25-智慧旅游系统(协同算法)三端
  • Redis:内存淘汰原则,缓存击穿,缓存穿透,缓存雪崩
  • 从零开始:如何打造一套完整的UI设计系统?
  • 数据可视化——让数据说话的魔法
  • java反射笔记、内省、动态代理
  • Redis 梳理汇总目录
  • torch.nn.Conv2d介绍——Pytorch中的二维卷积层
  • 体坛联播|郑钦文收获红土赛季首胜,国际乒联公布财报
  • 欧洲理事会前主席米歇尔受聘中欧国际工商学院特聘教授,上海市市长龚正会见
  • “80后”赵亮出任上海普陀区委副书记
  • 850亿元!2025年中央金融机构注资特别国债(一期)拟第一次续发行
  • 江苏省人社厅党组书记、厅长王斌接受审查调查
  • 多人称华为手机忽现拍照模糊疑存缺陷,售后回应:主摄像头故障