大家好,我是宁一。
SQL不仅仅是每个技术开发必须掌握的技能,
也是数据分析、商业分析招聘中,必考的能力。
这次给大家整理了SQL大厂春招的真题,每道题都加了独家详细解析。
整理完后,我的脑袋是蒙蒙的。
大厂就是大厂,这个烧脑程度,拜服!
之前也出过一篇大厂实战真题,大家可以一起食用。
2022年SQL大厂高频实战面试题(详细解析)
刷完这些题,相信大家能找到大厂出题的规律,大厂比较重视综合能力,题目不会只考一个知识点。
比如大多题目都综合考察了聚合函数、窗口函数、嵌套查询、索引、日期函数等知识点。
所以我们各个知识点都要熟练掌握。
这周六(3月26日)我会出SQL入门进阶课程。
不是广告,自己写的,免费的~
打算用最直白的语言给大家讲清楚SQL。从小白的角度入手,手把手教你学习SQL的入门以及进阶知识。
有些同学可能看过我之前的小程序实战课程,知道我的讲课风格就是:不说废话,只讲干货。
从最基础的增删改查,到进阶的视图、触发器、事件、事务等都会涉及。实战举例+作业巩固,争取用一门课让大家掌握SQL,可以顺利面试、参与工作。
感兴趣的同学可以关注蹲一下哦~
下面是大厂春招真题:
一、嵌套查询
嵌套查询,顾名思义,就是查询语句的嵌套,即在外部查询中还包含一个内部查询。
内部查询也叫子查询,查询结果可以作为一个临时表来使用,完成更为复杂表联结数据的检索功能。
嵌套查询是由内而外进行分析,子查询的结果作为主查询的查询条件。子查询中一般不使用order by子句,只能对最终查询结果进行排序。
经典问题:
下面表格是用户访问表users,记录了用户id(usr_id)和访问日期(log_date),查询出每个用户最近一次的登录记录和每个用户登录总次数(同一天多次登录认为是一次)。
实例结果:
解题思路:
根据示例结果,第二列current_day,是每个用户访问日期的最大值,直接用MAX聚合函数就可以。
第三列sum_day是每个用户登录总次数,因为同一天多次登录认为是一次,所以通过将原表log_date列格式化去掉时间,得出用户登录的日期,比如2021-05-03 01:00:08 格式化成 2021-05-03。我们就可以将日期去重,得到每个用户的登录总次数。
第一步:先将原表log_date列,通过DATE_FORMAT函数,进行日期的格式化。
第二步:再根据第一步得到的结果,将数据通过usr_id分组,并通过MAX聚合函数得到每组log_date列的最大值(也就是最近一次登录日期),通过COUNT聚合函数,得到用户登录总次数。
二、大厂综合考察真题
这道题涵盖的知识点很多,包括索引、日期函数、聚合函数、窗口函数、嵌套查询。
能做出来,说明SQL掌握的已经很棒了,可以放心去面试。
经典问题:
我们现在有一个数据表DateTable,如下:
问题一:对数据表DateTable的dates列添加索引。问题二:通过SQL语句,输入下方结果。
问题一:
这个就是考察索引语法的,很简单。
给DateTable表的dates列添加一个名为index_date的索引
查看索引
问题二:
解题思路:
我们查看输出结果,第一列是年,第二列是月,这两列直接用日期函数就可以得到。
第四列,是将cost列按年汇总,第五列是将cost列全部汇总,因为每一行都有汇总记录,所以我们不应该单纯用聚合函数SUM来计算,而是用窗口函数+聚合函数SUM。
第一步:我们先将前三列查询展示出来。
第二步:再根据第一步得到的结果,通过聚合函数SUM,结合窗口函数得到四五列。对窗口函数不了解的盆友,可以点击上一篇文章了解~
可以使用下方语句快速建表测试:
三、字节春招真题
经典问题:
查询支付日期在2022.3.20之后的购买商品超过一次的用户,按照最新购买时间倒叙排列。
解题思路:
先找出2022.3.20之后的数据记录,再将这些记录根据user_id进行分组,通过COUNT聚合函数查出每组条数大于1的记录,最后还要按照最新购买时间倒叙排列。
这道题看着很简单,但是里面埋了几个陷阱需要注意:
- having作用和where差不多,用来在分组之后,筛选分组才产生的数据。having后面可以直接跟聚合函数,如果要跟字段的话,这个字段必须在select后面提到过,where则不用
- MySQL中,在使用聚合函数的时候,select后面的字段,必须出现在group by的后面,比如这道题中的user_id字段。
- MySQL中,在使用聚合函数的时候,order_by后面的语句要注意使用聚合函数的字段,或者group by后面的字段。
上面的字段使用不太了解,没关系,我们来讲讲当一个查询语句同时出现where,group by,having,order by的时候,执行顺序和编写顺序,你就明白了。
FROM --> WHERE --> GROUP BY --> SELECT --> HAVING --> ORDER BY
我们再结合上面的题目看一下执行顺序:
1.执行where 语句对全表数据做筛选,FROM Products WHERE purchase_date>"2022-03-20”,返回第1个结果集。
2.针对第1个结果集使用group by分组,GROUP BY user_id,返回第2个结果集。
3.针对第2个结果集中的每1组数据执行SELECT user_id,有几组就执行几次,返回第3个结果集。
4.针对第3个结集执行HAVING COUNT(*)>1进行筛选,返回第4个结果集。
5.最后针对第4个结果集排序,ORDER BY max(purchase_date) desc
四、拼多多春招真题
经典问题:
现在有一个订单表orders,包括订单id(Oid)、商品id(product_id)、销售渠道(channel)、订单量(amount)。我们根据这个表,选取订单量前4的商品,并且选出每个商品订单量排名前2的销售渠道。
示例结果:
解题思路:
根据题目以及示例结果,我们最终要得到订单量最高的4个产品,以及每个产品对应排名前2的销售渠道。
我们可以先得到订单量排名前4的结果集1,再得到每个商品对应销售渠道的订单量排名结果集2,通过join将结果集1和结果集2连接得到最终结果。
第一步:首先获得订单量前4的商品,GROUP BY将产品分组之后,我们通过聚合函数SUM来获得每个产品的总订单量,命名为amt,再将amt倒序排序,通过limit 4得到订单量前4的商品。
第二步:我们再得到每个商品对应销售渠道的订单量排名
第三步:将第一步和第二步的结果通过product_id列进行join链接,并限定条件第二步得到的rk排名列<=2。最终结果如下:
五、美团春招真题
现在有一个Products表,推荐出每个user_id,和他相似的用户所购买过的product。
要求:该用户已经购买过的不再推荐。
相似用户的定义:曾经购买过2种或2种以上的相同商品。
示例结果:
解题思路:
这道题我们先找出相似的用户,比如用户A和用户B是相似用户,我们需要将B购买过,而A没有购买过的产品推荐给A。这个跟实际业务很相似了,还需要费点脑筋的,我们来一步步拆解。
第一步:我们先找出相似的用户,也就是购买相同的商品>=2的用户。用到了自连接,找到不同用户对应相同商品的记录。再通过COUNT计算每个用户有多少条这样的记录。
第二步:将第一步得到的结果集,再通过uid_a连接Products表,连接条件是x.uid_a = y.user_id,这一步是为了得到product_id这一列。
第三步:将第二步得到的结果集,再通过uid_b左连接Products表,连接条件是x.uid_b = z.user_id,y.product_id = z.product_id。
我们用的是左连接,即使不满足y.product_id = z.product_id,第二步获得的结果集也会全部显示,不满足条件的会显示null。这一步结果已经出来了,就是第四列为null 的记录。
第四步:根据第三步获得的结果集,我们判断第四列z.product_id为null,并且显示第二列x.uid_b和第三列y.product_id,就是最终的答案了。
最终结果如下:
六、快手春招真题
现在有主播表a:包括主播id(upid)、直播间id(rid)、开播时间(stime)
观众表b:包括观众id(uid)、进入的直播间id(rid)、进入时间(intime)
找出开播三分钟内无人进入的直播房间号。
解题思路:
我们先通过左连接,得到主播对应的3分钟进入直播间的观众,如果没有对应的观众,就是我们要找的记录。
第一步:将主播表a和观众表b进行左连接,条件是直播间id(rid)相同,并且主播开播时间(stime)大于(观众进入时间减去3分钟)。符合这个条件的主播,说明开播3分钟内有观众进入直播间。
比如主播是12:10分开播,观众在12:12分进入,这符合开播3分钟内进入的要求。
用数据表示就是:观众时间减去3分钟,是12:09分,12:10分>12:09分,说明用户在开播3分钟内进入直播间。
第二步:第一步得到的结果集,第三列b.uid如果为null,说明这个直播间开播3分钟内没有观众进入。所以我们再添加一个where条件就可以了。