社招面试高频题:MySQL 子查询到底怎么答才满分?

75 阅读6分钟



大家好呀,我是31岁的小米,一个对技术痴迷、爱分享故事的大哥哥。上周末在咖啡馆里,我经历了一场“心跳加速”的面试模拟,把我逼出了新高度。面试官抛来的一句话就让我脑子里闪过无数个 SQL 片段,他问我——

“小米,能不能聊聊你对 MySQL 子查询的理解?它有哪些情况?”

当时我差点一口咖啡呛出来,心里喊着:“这不是我刚刚复习过的吗?幸好昨天晚上临时抱佛脚了!”

今天呢,我就把当时的回答和我平时踩过的坑,整理成一篇长文,分享给正在准备面试的小伙伴们。别小看这道题,它经常在社招面试里出现,而且考察的不只是你会写 SQL,而是你能不能把原理+场景讲透。

什么是子查询?

先来个故事开场。

有一次我和朋友去吃火锅,我们点了一堆菜。朋友突然问我:

“小米,咱们今天吃的肉里面,哪一盘是最便宜的?”

我翻菜单的时候,脑子里就形成了两步逻辑:

  • 先查出所有肉类的价格
  • 再在这些价格中,选出最便宜的那一盘

这其实就是“子查询”的思路。

子查询(Subquery) ,顾名思义,就是一条 SQL 语句嵌套在另一条 SQL 语句里,它的查询结果会作为外层查询的条件或者数据来源。

换句话说:

  • 条件:子查询的结果,可以作为外层 SQL 的查询条件
  • 嵌套:子查询本身是 SQL 的一部分,像一个“临时助手”,帮助外层 SQL 完成任务

总结一句话:子查询就是把一个查询的结果,当成另一个查询的输入。

子查询的两大特征

子查询虽然听起来高级,其实有两个特征特别容易记:

  • 条件特征: 子查询的结果,常常作为父查询的条件使用,比如 WHERE、HAVING、FROM、SELECT 里都能出现。
  • 嵌套特征: 子查询一定是嵌套的,内部 SQL 的结果得先出来,才能被外部 SQL 用到。

所以你可以把子查询理解成“先打草稿,再给最终答卷”。

子查询的三种情况

好了,接下来进入重头戏,也是面试官最关心的地方:子查询分三种情况。

这三种情况,就像三个层次的火锅套餐,从“一个小菜”到“一整桌宴席”,层层递进。

单行单列的子查询 —— 返回一个值

这种情况最简单,就像你问我:

“小米,你朋友里谁年龄最小?”

我查一圈,结果只有一个人,一个年龄。SQL 写出来就是这样:

这里 (SELECT MIN(age) FROM student) 就是一个子查询,它返回的结果只有一行一列,也就是一个值。

所以父查询的条件可以直接用 =、<、> 等运算符去比较。

关键点

  • 单行单列子查询返回的就是一个“具体的值”
  • 常常搭配 =、<、> 等运算符使用

这就像单选题,答案只有一个。

多行单列的子查询 —— 返回一个数组

如果换个问题:

“小米,班里哪些同学的成绩在前 3 名?”

这时候结果就不是一个人,而是三个人。返回的就是一个“数组”。SQL 可以这么写:

这里 (SELECT score FROM student ORDER BY score DESC LIMIT 3) 返回了多个分数,但是只有一列。父查询就可以用 IN 来判断。

关键点

  • 多行单列子查询返回的结果像一个数组
  • 常常搭配 IN、ANY、ALL 等关键字使用

比如:

  • IN 表示“在这些结果里”
  • ANY 表示“和其中任意一个比较”
  • ALL 表示“和所有结果比较”

这就像多选题,有多个答案可以选。

多行多列的子查询 —— 返回一张虚拟表

最后一种情况就比较有意思了,它返回的不是一个值,也不是一列,而是一张表。

比如:

“小米,给我一份‘平均分高于 80 的所有班级名单和平均分’。”

这时候子查询必须先算出每个班级的平均分,再筛选出大于 80 的班级,最后外层 SQL 再来用。SQL 写法:

这里 (SELECT class, AVG(score) ... ) 就是一张“虚拟表”,外层查询可以直接在这张虚拟表上再做过滤。

关键点

  • 多行多列子查询返回的结果是一张临时表
  • 不能直接用于 WHERE 条件
  • 常常用于 FROM 子句,或者 SELECT 子句

这就像是“整套题卷子”,外层 SQL 可以把它当一张表来继续查询。

三个场景的对比总结

一句话总结:

  • 单行单列 = 单选题
  • 多行单列 = 多选题
  • 多行多列 = 表格题

真实面试小故事

我当时在面试现场,就是按这个逻辑回答的:

  • 先解释子查询是什么(条件 + 嵌套)
  • 再分三种情况,举了例子
  • 最后做了个总结对比表格

面试官笑着点头,说:“嗯,小米回答得很清晰,说明你不光会写,还能讲明白逻辑。”

那一刻,我内心 OS:这回应该稳了!

子查询的坑点与优化

说了这么多,别忘了子查询也有坑。比如:

  • 性能问题: 子查询如果结果集很大,容易拖慢查询速度。很多时候可以用 JOIN 来代替子查询。
  • 可读性问题: 子查询层级太深时,SQL 可读性差,维护麻烦。建议加别名,逻辑拆清楚。
  • LIMIT 陷阱: 有些子查询里加 LIMIT 会报错,尤其是当它出现在 IN 子句里时,要注意 SQL 方言的兼容性。

所以,不要盲目地觉得子查询万能。面试官如果追问,你也可以顺势补一句:

“子查询虽然方便,但在大数据量场景下我更倾向于用 JOIN 来优化性能。”

这样回答,绝对加分。

写在最后

子查询,是 SQL 世界里的一把瑞士军刀,灵活好用,场景丰富。它考察的不仅是你能不能写出 SQL,还考察你能不能把复杂逻辑分解成多个小步骤,再组合起来。

我常跟小伙伴说,学 SQL 就像打游戏,你得知道武器什么时候用,怎么用才高效。子查询,就是那把灵巧的小刀,用得好能轻松过关,用不好就会卡死在性能里。

希望这篇文章能帮你在面试中游刃有余。下次遇到面试官抛来这道题的时候,你也能自信地笑一笑,说:

“子查询嘛,分三种情况:单行单列、多行单列、多行多列。”

面试官一定会对你刮目相看。

END

如果这篇文章对你有帮助,记得点个赞呀! 我会继续分享更多面试高频 SQL 知识点,让我们一起从容应对社招面试!

我是小米,一个喜欢分享技术的31岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货!