LeetCode SQL入门:8道基础题掌握80%查询场景

发布时间:2026/10/31 18:36:26
LeetCode SQL入门:8道基础题掌握80%查询场景

1. LeetCode SQL 阶段0:8道基础题精解

最近在帮团队新人做SQL入门培训时,发现很多同学虽然看过SQL语法,但遇到实际问题时还是无从下手。这让我想起自己当年刷LeetCode SQL题的经历——从最基础的SELECT开始,通过8道典型题目就能掌握80%的日常查询场景。下面就用这8道经典题为例,带大家系统梳理SQL基础操作。

提示:本文所有题目均来自LeetCode免费题库,使用MySQL语法标准,适合零基础或需要巩固基础的开发者

2. 基础查询:SELECT核心四件套

2.1 简单查询与条件过滤

题目175. 组合两个表(难度:简单)要求从Person表和Address表中联合查询姓名和地址信息。这道题考察最基础的:

SELECT p.FirstName, p.LastName, a.City, a.State FROM Person p LEFT JOIN Address a ON p.PersonId = a.PersonId

这里有几个关键点:

  1. 必须使用LEFT JOIN保证没有地址的人也能显示
  2. 表别名(p/a)让代码更简洁
  3. SELECT字段明确指定来源表避免歧义

踩坑记录:早期我常忘记写ON条件导致笛卡尔积,结果集暴涨百万倍!

2.2 数据筛选与排序

题目176. 第二高的薪水(难度:简单)演示了WHERE和LIMIT的经典组合:

SELECT ( SELECT DISTINCT Salary FROM Employee ORDER BY Salary DESC LIMIT 1 OFFSET 1 ) AS SecondHighestSalary

特别注意:

  • 子查询解决"没有第二高时返回null"的要求
  • DISTINCT避免相同薪水重复计数
  • OFFSET 1跳过第一条记录

3. 条件逻辑与分组统计

3.1 CASE WHEN条件分支

题目177. 第N高的薪水(难度:中等)需要创建函数返回第N高的薪水:

CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT BEGIN SET N = N - 1; RETURN ( SELECT DISTINCT salary FROM employee ORDER BY salary DESC LIMIT 1 OFFSET N ); END

这个解法揭示了LIMIT OFFSET的数学本质:

  • OFFSET N = 跳过前N条
  • 所以N需要减1才能对应题目描述

3.2 分组统计与HAVING

题目178. 分数排名(难度:中等)展示了窗口函数的威力:

SELECT score, DENSE_RANK() OVER (ORDER BY score DESC) AS 'rank' FROM Scores

对比三种排名函数:

  • RANK(): 并列会跳过后续名次(1,2,2,4)
  • DENSE_RANK(): 并列不跳名次(1,2,2,3)
  • ROW_NUMBER(): 强制连续(1,2,3,4)

4. 多表操作与复杂逻辑

4.1 自连接查询

题目180. 连续出现的数字(难度:中等)需要找出至少连续出现三次的数字:

SELECT DISTINCT l1.Num AS ConsecutiveNums FROM Logs l1 JOIN Logs l2 ON l1.Id = l2.Id - 1 JOIN Logs l3 ON l2.Id = l3.Id - 1 WHERE l1.Num = l2.Num AND l2.Num = l3.Num

关键技巧:

  • 通过Id-1实现行与下一行的关联
  • 三重自连接确保连续三次
  • DISTINCT去重相同数字

4.2 子查询优化

题目181. 超过经理收入的员工(难度:简单)演示了自连接的另一种用法:

SELECT e1.Name AS Employee FROM Employee e1 JOIN Employee e2 ON e1.ManagerId = e2.Id WHERE e1.Salary > e2.Salary

性能对比:

  • 子查询版本(效率低):
    SELECT Name FROM Employee e1 WHERE Salary > (SELECT Salary FROM Employee WHERE Id = e1.ManagerId)
  • 自连接版本在大数据量时性能更优

5. 实战问题排查指南

5.1 常见错误代码速查

错误现象可能原因解决方案
结果为空连接条件错误检查ON后字段是否关联正确
重复数据忘记DISTINCT添加DISTINCT或检查GROUP BY
性能低下全表扫描对WHERE条件字段建立索引

5.2 执行计划分析技巧

以题目182. 查找重复的电子邮箱为例:

-- 原始写法 SELECT Email FROM Person GROUP BY Email HAVING COUNT(*) > 1 -- 优化写法(使用临时表) WITH email_counts AS ( SELECT Email, COUNT(*) as cnt FROM Person GROUP BY Email ) SELECT Email FROM email_counts WHERE cnt > 1

使用EXPLAIN分析可以看到:

  • 原始写法需要全表扫描
  • 优化写法能利用索引(如果有)

6. 进阶学习路线建议

完成这8道题后,可以继续挑战:

  1. 窗口函数进阶(LEAD/LAG等)
  2. 递归CTE查询
  3. 复杂JOIN优化
  4. 索引设计与优化

我个人的学习心得是:每道题至少尝试两种解法,比较执行计划差异。比如题目185. 部门工资前三高的员工,既可以用窗口函数:

SELECT Department, Employee, Salary FROM ( SELECT d.Name AS Department, e.Name AS Employee, e.Salary, DENSE_RANK() OVER (PARTITION BY d.Name ORDER BY e.Salary DESC) AS rnk FROM Employee e JOIN Department d ON e.DepartmentId = d.Id ) t WHERE rnk <= 3

也可以用相关子查询实现,后者在MySQL 5.7以下版本可能性能更好。