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

这道经典SQL面试问题你会吗?

大家经常自嘲后端开发就是crud boy嘛,今天给大家看一道SQL题,我相信很多人写不出来。我们来看一下这个题目。

create table course (id int primary key,name varchar(32) not null
);
create table student (id int primary key,name varchar(32) not null
);
create table score (id int primary key,course_id int not null,student_id int not null,score int not null
);

这三张表也是我经常在面试里面有问到的,这三张表的含义是非常好理解的,但是基于这三张表可以研发出来很多复杂的业务场景SQL面试题。我们先初始化一些课程信息和学生分数信息。

insert into course values(1,`语文`),(2,`数学`),(3,`外语`);
insert into student values(1,`小张`),(2,`小王`),(3,`小马`);
insert into score values(1,1,1,80),(2,2,1,90),(3,3,1,70);
insert into score values(4,1,2,70),(5,2,2,90),(6,3,2,80);
insert into score values(7,1,3,80),(8,2,3,60),(9,3,3,70);

总分最高的学生

求总分最高的学生他的分数是多少?这个题目其实是有一些歧义的,是总分最高呢,还是单科最高呢?作为面试的你对于题意本身理解不清晰的情况下,你应该反问面试官,而不是直接就开始写。
我们把这两种情况都来写一下,先求总分最高的学生,找到这个score表,那既然是总分,我们肯定要用sum函数,那既然用到sum,那是不是要做一个分组,基于什么分组呢?目标是要求总分最高的学生,自然想到应该基于student_id去分组,通过score表按照student_id分组我们就能拿到总分及相应的student_id,但怎么查到学生的名字呢?
很多同学很自然而然就想到去join这个student的表,但是这里隐藏一个问题,就是总分最高的可能不止一个学生,我们是通过总分进行的分组,分组后只能取到其中某一个student_id。那应该怎么去做呢?其实还要再去查一遍这个score表,把相应取得这个总分的学生的所有id都查出来,然后再去跟student的做一个连接,这样才能查出完整的数据。这个思路清晰了之后,我们的SQL语句步骤如下:

  1. 查出最高分
select sum(score) from score group by student_id order by sum(score) desc limit 1
  1. 查出最高分所有的学生ID。
select distinct(student_id) from score 
group by student_id having sum(score)=(select sum(score) from score 
group by student_id order by sum(score) desc limit 1) 
  1. join学生信息表得到获得最高分的学生信息
select s.name,t.score from student s 
right join (select distinct(student_id), sum(score) from score 
group by student_id having sum(score)  = (select sum(score) from score 
group by student_id order by sum(score) desc limit 1)) t on s.id = t.student_id

单科最高的学生

大家想一下,单科最高的话应该是要通过课程去分组,同样的获取每个单科分数最高的学生可能也不止一个,所以分组后你还要去跟score再去做一次连接,基于course id跟max score再去连一下score表从而得到每一科最高分的学生的id。
所以这个问题也是分三步,第一步就是通过course id去分组查到单科的最高分,第二步就是通过这个score表再去跟这个最高分和对应的课程id去进行right join。这里为什么是right join 大家可以思考一下,这样就查到了取得这个课程最高分的所有学生,这一步写出来了,其实最后就很简单了,去连接两个学生表跟课程表就能拿到学生的名字跟课程的名字,得到最终的SQL语句:

select s.name,c.name,s2.max_score from score s1 
right join (select max(score) max_score,course_id from score 
group by course_id) on s1.course_id = s2.course_id and s1.score=s2.max_score
left join course c on c.id = s1.course_id left join student s on s.id = student_id

虽然大部分互联网公司这种自动化的SQL生成器,也并不建议在系统里面去做连接查询,但是也有很多情况,比如说产品、运营要拉一些数据,排查一些线上问题,确实要去写一些比较复杂的CQL,而且你能写出这个SQL,代表你有两个能力,第一个就是你对业务本身理解是比较到位的,第二个就是你Sql本身的功底也是比较扎实的。
互联网行业不景气,但切莫心浮气躁,打牢基本功,才能厚积薄发!

关注公众号【小白技术圈】,回复f04即可获得2023最新全套面试资料

http://www.lryc.cn/news/218893.html

相关文章:

  • 网络服务退出一个问题的解析
  • 第四次pta认证P测试
  • mysql:B+树/事务
  • python-在系统托盘显示CPU使用率和内存使用率
  • 构建mono-repo风格的脚手架库
  • 云安全—etcd攻击面
  • 类锁和实例对象锁你分清了吗?
  • 如何在麒麟上安装 ONLYOFFICE 桌面编辑器
  • 记录:如何编写linux驱动,用module的方式
  • 3款免费又好用的 Docker 可视化管理工具
  • C语言--判断一个年份是否是闰年(详解)
  • Python---排序算法
  • gitlab Blocking and unblocking users
  • Swift 和 Python 两种语言中带关联信息错误(异常)类型的比较
  • 北京联通iptv组播配置
  • C++ STL 迭代器失效
  • 麒麟KYLINIOS软件仓库搭建02-软件仓库添加新的软件包
  • 专业媒体播放软件Movist Pro中文
  • 数据结构-邻接表广度优先搜索(C语言版)
  • Py之auto-gptq:auto-gptq的简介、安装、使用方法之详细攻略
  • 【Linux】Linux+Nginx部署项目(负载均衡动静分离)
  • C++笔记之vector的成员函数swap()和data()
  • Linux centos环境 安装谷歌浏览器
  • go-gin-vue3-elementPlus带参手动上传文件
  • 艺术的维度:洞察AI诈骗,优雅防范之艺术
  • JavaScript的作用域和作用域链
  • 电脑文件批量重命名攻略:高效操作技巧助您轻松完成任务
  • 四、三种基本程序结构
  • 深入理解元素的高度、行高、行盒和vertical-align
  • 什么叫储能能量管理单元EMU?储能能量管理单元EMU功能?储能EMU是什么?储能能量管理系统如何实现一次调频AGC-AVC功能?