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 表;
相关推荐
会飞的架狗师2 小时前
【MySQL体系】第4篇:MySQL 查询优化实用技巧
数据库·mysql
lypzcgf3 小时前
Coze源码分析-资源库-编辑数据库-前端源码-核心组件
前端·数据库·源码分析·coze·coze源码分析·ai应用平台·agent平台
wei_shuo3 小时前
KingbaseES聚焦产品上线
数据库·kingbasees
AI浩3 小时前
Redis中的RPOP、BRPOP、LPOP 和 BLPOP
数据库·chrome·redis
数据和云4 小时前
从Databricks和Supabase看AI时代的中国数据库启示
数据库·人工智能
我科绝伦(Huanhuan Zhou)4 小时前
Oracle ADRCI工具全面使用指南:从基础到故障诊断实战
数据库·oracle
数据库生产实战4 小时前
Oracle LOB使用入门和简单使用,提供学习用的测试用例!
数据库·学习·oracle
武子康4 小时前
Java-144 深入浅出 MongoDB BSON详解:MongoDB核心存储格式与JSON的区别与应用场景
java·开发语言·数据库·mongodb·性能优化·json·bjson
Raymond运维4 小时前
MySQL包安装 -- SUSE系列(SUSE资源库安装MySQL)
linux·运维·数据库·mysql