sql练习题单-知识点总结

一、题单

力扣

题目分类 经典题目 核心考点 难度
基础查询与过滤 1757. 可回收且低脂的产品 595. 大的国家 1148. 文章浏览 I WHERE条件过滤、OR逻辑运算符 简单
表连接(JOIN) 1378. 使用唯一标识码替换员工ID 1068. 产品销售分析 I 577. 员工奖金 1581. 进店却未进行过交易的顾客 1251. 平均售价 LEFT JOININNER JOIN、多表连接、连接条件与过滤 简单-中等
排序、分组与聚合 182. 查找重复的电子邮箱 1484. 按日期分组销售产品 619. 只出现一次的最大数字 1174. 即时食物配送 II GROUP BYHAVINGCOUNT(DISTINCT)GROUP_CONCAT 简单-中等
子查询与高级功能 176. 第二高的薪水 570. 至少有5名直接下属的经理 185. 部门工资前三高的所有员工 610. 判断三角形 子查询、CASE WHENIFNULL/COALESCE、逻辑判断 中等
窗口函数 178. 分数排名 RANK()DENSE_RANK()ROW_NUMBER()

题目详解:

182

sql 复制代码
SELECT 
    sell_date,
    COUNT(DISTINCT product) AS num_sold, 
    GROUP_CONCAT(DISTINCT product ORDER BY product SEPARATOR ',') AS products
FROM 
    Activities
GROUP BY 
    sell_date
ORDER BY 
    sell_date ASC;
部分 说明
GROUP_CONCAT(...) MySQL 特有函数,把一组中的多个值拼接成一个字符串
DISTINCT product 只取不同的产品名(去重)
ORDER BY product 拼接时按产品名的字母顺序排列
SEPARATOR ',' 用逗号 , 作为分隔符(默认就是逗号,可省略)
AS products 给拼接结果起别名
函数/语法 用途 注意
GROUP BY 按某字段分组 是聚合操作的基础
COUNT(DISTINCT col) 统计去重后的数量 非常常用
GROUP_CONCAT() 将多行值拼成字符串 MySQL 特有
ORDER BY in GROUP_CONCAT 控制拼接顺序 否则顺序不确定
SEPARATOR ',' 自定义分隔符 可改为 ; 或 `

这种写法常用于:

  • 日报:每天卖了哪些商品?
  • 用户行为分析:每个用户购买了哪些类目?
  • 标签系统:每个人有哪些标签?

总结一句话:

这段 SQL 的核心思想是:

"按日期分组 → 去重统计 → 拼接字符串"

178

sql 复制代码
SELECT
  S.score,
  DENSE_RANK() OVER (
    ORDER BY
      S.score DESC
  ) AS 'rank'
FROM
  Scores S;

这是最核心的部分,我们拆开讲:

部分 说明
DENSE_RANK() 一个窗口函数(Window Function),用于生成密集排名
OVER (...) 定义窗口函数的作用范围和排序规则
ORDER BY S.score DESC 按分数 从高到低 排序(DESC = 降序)
AS 'rank' 将排名结果命名为 'rank'(注意:rank 是保留字,所以用引号)

176

sql 复制代码
# Write your MySQL query statement below
SELECT
    IFNULL(
      (SELECT DISTINCT Salary
       FROM Employee
       ORDER BY Salary DESC
        LIMIT 1 OFFSET 1),
    NULL) AS SecondHighestSalary
1. 内层子查询:找出第二高的薪水
步骤 说明
DISTINCT Salary 去重:相同薪水只保留一个(避免重复影响排名)
ORDER BY Salary DESC 按薪水从高到低排序(最高在前)
LIMIT 1 OFFSET 1 跳过第 1 行,取 1 行 - OFFSET 1:跳过最高薪 - LIMIT 1:取接下来的 1 条(即第二高)
. 外层:IFNULL(..., NULL)
复制代码

sql

编辑

复制代码
IFNULL( 子查询结果 , NULL )
  • IFNULL(value, default):如果 valueNULL,就返回 default
  • 这里 default 也是 NULL,看起来"多此一举",其实非常关键!
🤔 为什么需要 IFNULL

考虑一种情况:

  • 表里只有 1 个员工,或者所有人薪水都一样
  • 那么子查询 LIMIT 1 OFFSET 1查不到任何数据
  • 查不到数据 → 返回 NULL
  • SELECT NULL 仍然会返回一行 NULL,而不是"空结果

核心考点与刷题技巧

根据搜索结果显示,以下这些是面试中频繁出现的核心考点,你需要特别注意:

  • NULL值处理 :这是面试官的挚爱考点。 搜索结果显示,在过滤条件中,NULL不能直接用 =!= 比较,必须使用 IS NULLIS NOT NULL。例如"寻找用户推荐人"一题,referee_id != 2 不会包含 referee_idNULL 的记录。

  • 表连接与连接条件:务必理解清楚不同JOIN的区别。

    • 多表连接 :如"学生们参加各科测试的次数"一题,需要先通过CROSS JOIN生成所有学生和所有科目的组合,再LEFT JOIN考试成绩,才能确保不漏掉任何学生-科目组合。

    • 连接条件与过滤ONWHERE的执行顺序不同,会影响结果。例如"平均售价"一题,需要将purchase_date BETWEEN start_date AND end_date这个条件放在ON子句中,而不是WHERE里,否则会错误地过滤掉没有销售记录的产品。

  • 聚合函数与CASE WHENCASE WHENAVG等聚合函数结合,可以巧妙地计算比率。在"确认率"一题中,使用AVG(CASE WHEN action = 'confirmed' THEN 1 ELSE 0 END)可以简洁地得出确认率,并自动处理NULL值。

  • 窗口函数 :这是解决复杂问题的利器,常用于排名、累计求和等问题。你需要掌握ROW_NUMBER(), RANK(), DENSE_RANK()的区别,以及SUM() OVER()的用法。

我的解题思路4步

1.查什么

直接从题意或者输出,知道SELECT什么,有的内容需要处理列入count(xx)as x,或者再内嵌一个函数窗口函数什么的。

2.确表源,

from,以及表之间的关系,jion

from xxx left join ccc

on xxx.id=ccc.id

3.找条件,

普通查询

where 条件

order by xxx ESC(升序)/DESC(降序)

LIMIT 数量

分组统计

where

group by xxx

having 过滤条件。

4.完成构建检查。

高频考点速记:

• 分组统计 → GROUP BY + HAVING

• 多表关联 → JOIN ON

• 排名问题 → ROW_NUMBER/RANK

• 连续问题 → LAG/LEAD + 日期计算

• 空值处理 → COALESCE/IFNULL

基础查询模板

1. 简单查询框架

sql

复制代码
SELECT 字段 
FROM 表 
WHERE 条件 
ORDER BY 排序字段 
LIMIT 数量;

2. 分组统计模板

sql

复制代码
SELECT 分组字段, 聚合函数(统计字段)
FROM 表 
WHERE 过滤条件 
GROUP BY 分组字段 
HAVING 分组后过滤条件;

3. 内连接模板

sql

复制代码
SELECT A.字段, B.字段
FROM 表A A
INNER JOIN 表B B ON A.关联字段 = B.关联字段;

4. 左连接模板

sql

复制代码
SELECT A.字段, B.字段
FROM 表A A
LEFT JOIN 表B B ON A.关联字段 = B.关联字段;

5. 排名前N模板

sql

复制代码
SELECT 字段
FROM (
    SELECT 字段,
           ROW_NUMBER() OVER (ORDER BY 排序字段 DESC) as rn
    FROM 表
) t
WHERE rn <= N;

6. 部门排名模板

sql

复制代码
SELECT 字段
FROM (
    SELECT 字段,
           RANK() OVER (PARTITION BY 部门字段 ORDER BY 薪资字段 DESC) as rank
    FROM 表
) t
WHERE rank = 1;

7. 累计统计模板

sql

复制代码
SELECT 日期字段, 数值字段,
       SUM(数值字段) OVER (ORDER BY 日期字段) as 累计值
FROM 表;

8. 同比环比模板

sql

复制代码
SELECT 日期, 数值,
       LAG(数值, 1) OVER (ORDER BY 日期) as 上月数值,
       (数值 - LAG(数值, 1) OVER (ORDER BY 日期)) / LAG(数值, 1) OVER (ORDER BY 日期) as 增长率
FROM 表;

9. 连续登录模板

sql

复制代码
SELECT user_id, COUNT(*) as 连续天数
FROM (
    SELECT user_id, login_date,
           DATE_SUB(login_date, INTERVAL ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY login_date) DAY) as flag
    FROM login_records
) t
GROUP BY user_id, flag
HAVING COUNT(*) >= N;

10. 空值替换模板

sql

复制代码
SELECT COALESCE(字段, 默认值) as 新字段名
FROM 表;
相关推荐
科技小花39 分钟前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
一江寒逸41 分钟前
零基础从入门到精通MySQL(中篇):进阶篇——吃透多表查询、事务核心与高级特性,搞定复杂业务SQL
数据库·sql·mysql
D4c-lovetrain43 分钟前
linux个人心得22 (mysql)
数据库·mysql
阿里小阿希1 小时前
CentOS7 PostgreSQL 9.2 升级到 15 完整教程
数据库·postgresql
荒川之神1 小时前
Oracle 数据仓库雪花模型设计(完整实战方案)
数据库·数据仓库·oracle
做个文艺程序员2 小时前
MySQL安全加固十大硬核操作
数据库·mysql·安全
不吃香菜学java2 小时前
Redis简单应用
数据库·spring boot·tomcat·maven
一个天蝎座 白勺 程序猿2 小时前
Apache IoTDB(15):IoTDB查询写回(INTO子句)深度解析——从语法到实战的ETL全链路指南
数据库·apache·etl·iotdb
不知名的老吴2 小时前
Redis的延迟瓶颈:TCP栈开销无法避免
数据库·redis·缓存
YOU OU2 小时前
三大范式和E-R图
数据库