面试加分项!CASE WHEN 两种写法、CTE 公共表表达式、四大类窗口函数,老哥一次讲透

同学,窗口函数和 CTE 是 MySQL 进阶的分水岭,也是面试官判断你 "有没有系统学过" 的题。这篇是加分项,可得拿下。

一、CASE WHEN:两种写法都要会

复制代码
-- 写法一:简单 CASE(等值判断)
SELECT name,
       CASE gender WHEN '男' THEN 'M' ELSE 'F' END AS g
FROM student;

-- 写法二:搜索 CASE(条件判断,更灵活)
SELECT name, age,
       CASE
         WHEN age < 18 THEN '未成年'
         WHEN age < 60 THEN '成年'
         ELSE '老年'
       END AS stage
FROM student;

CASE WHEN 还能用在 WHERE (动态过滤)、ORDER BY (自定义排序)、GROUP BY (自定义分组)。 三个注意点: ① 必须写 END;② 按顺序返回第一个匹配的;③ 建议写 ELSE 兜底。

二、CTE(WITH,MySQL 8.0 新功能)

复制代码
-- 场景:查高于部门平均工资的员工
WITH dept_avg AS (
    SELECT dept_id, AVG(salary) AS avg_sal
    FROM emp
    GROUP BY dept_id
)
SELECT e.*
FROM emp e
JOIN dept_avg d ON e.dept_id = d.dept_id
WHERE e.salary > d.avg_sal;

作用:把复杂查询拆成可读的临时结果集,让 SQL 模块化、可复用,比嵌套子查询清爽得多。

三、窗口函数(核心区别:不减少行数)

窗口函数和聚合函数最大的区别:

  • 聚合函数 把多行压成一行(AVG 返回一个值)。
  • 窗口函数 不压缩行数,每一行都返回结果,适合算排名、移动平均这种。

1)排序类(最常考):

复制代码
SELECT name, dept_id, salary,
    ROW_NUMBER() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS rn,    -- 严格连续 1,2,3
    RANK()       OVER (PARTITION BY dept_id ORDER BY salary DESC) AS rk,    -- 有并列就跳号 1,1,3
    DENSE_RANK() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS drk    -- 有并列不跳号 1,1,2
FROM emp;

区别记住:ROW_NUMBER 永远连续;RANK 并列跳号;DENSE_RANK 并列不跳号。面试常让三选一。

2)聚合类:

复制代码
-- 累计求和(跑了多少天卖了多少)
SELECT date, amount,
       SUM(amount) OVER (ORDER BY date) AS running_total
FROM sales;

3)偏移类(LAG / LEAD):

复制代码
-- 看"今天和昨天的差距"
SELECT date, amount,
       LAG(amount)  OVER (ORDER BY date) AS prev_amount,   -- 上一条
       LEAD(amount) OVER (ORDER BY date) AS next_amount    -- 下一条
FROM sales;

4)首尾类(FIRST_VALUE / LAST_VALUE / NTH_VALUE):

复制代码
-- 每个部门最高薪资
SELECT name, dept_id, salary,
       FIRST_VALUE(salary) OVER (PARTITION BY dept_id ORDER BY salary DESC) AS highest_sal
FROM emp;

老哥一句话:窗口函数 OVER() 里的 PARTITION BY 相当于 "分组",ORDER BY 相当于 "组内排序",先想清楚你要按什么分组、按什么排序,再选函数,就错不了。MySQL 8.0 才支持窗口函数。

相关推荐
bksczm1 小时前
InnoDB 内存结构总览:Change Buffer、AHI 与 Log Buffer
数据库·mysql
招风的黑耳1 小时前
SpringBoot+Vue+MySQL 民宿在线预定平台 完整可运行版(源码+文档)
vue.js·spring boot·mysql
.痞老板.3 小时前
mysql初阶--数据库设计
数据库·mysql·oracle
Decay__5 小时前
SQL Server 数据库全栈运维实战系列 — 合集索引(24 篇)
运维·数据库·sql·mysql·架构
Thanks_ks5 小时前
SQL 的 GROUP BY 与聚合函数:从会写 SELECT 到会做统计
数据库·sql·mysql·group by·数据统计·聚合函数·having
Decay__13 小时前
12_MySQL InnoDB 内存与锁调优 —— Buffer Pool、redo log、隔离级别与锁等待
运维·数据库·sql·mysql·架构
苏宸啊17 小时前
MySQL(一)
数据库·mysql
2603_9696948518 小时前
JDBC 基础学习笔记:API 核心原理解析与 CRUD 代码实操
数据库·笔记·mysql·学习方法·database·sql注入
这个DBA有点耶18 小时前
库内语义构建 vs 外挂向量库:业务语义缺失,才是RAG“胡说八道”的根源
数据库·mysql·aigc