当前位置: 首页 > news >正文

MySQL复盘②

第8-15题 题目原文

8.使用窗口函数row_number(),查询每个部门中按工资降序排列的员工排名。

9.使用窗口函数rank(),查询所有员工按工资降序的排名。

10.使用窗口函数dense_rank(),查询所有员工按工资降序的排名。

11.使用 CTE,先查询出每个部门的平均工资,再查询平均工资高于 8500 的部门及其平均工资。

12.使用 CTE,查询每个部门工资排名前 2 的员工(按工资降序)。

13.查询工资比所在部门平均工资高的员工姓名、工资和部门编号(使用子查询作为条件)。

14.使用窗口函数,查询每个部门的员工按工资降序排列,并计算该员工工资占部门总工资的百分比。

15.使用窗口函数row_number(),查询整个公司工资排名第 3 到第 5 名的员工姓名、工资和排名。

第8-15题 考点对照

题号核心考点
8row_number()+partition by
9rank()全公司排名(跳号)
10dense_rank()全公司排名(不跳号)
11CTE + 聚合函数 + 关联查询
12CTE +row_number()+ 筛选前N名
13关联子查询(比所在部门平均工资高)
14窗口函数sum() over()+ 百分比计算
15CTE +row_number()+between范围筛选
#8selectemployees.emp_name,employees.dept_id,employees.salary,row_number()over(partitionbydept_idorderbysalarydesc)as'排行'fromemployees;#9selectemp_name,employees.salary,rank()over(orderbysalarydesc)as'排行'fromemployees;#10selectemp_name,employees.salary,dense_rank()over(orderbysalarydesc)as'排行'fromemployees;#11/* with 临时表名 as ( 子查询语句 ) select * from 临时表名; *//*子查询 平均工资 select dept_id, avg(employees.salary) as avgs from employees group by dept_id; */witht11as(selectdept_id,avg(employees.salary)asavgsfromemployeesgroupbydept_id)selectdept_name,avgsfromt11joindepartmentsondepartments.dept_id=t11.dept_idwhereavgs>8500;#12/* select *, row_number() over (partition by employees.dept_id order by employees.salary desc ) as srank from employees; *//* with t12 as ( select *, row_number() over (partition by employees.dept_id order by employees.salary desc ) as srank from employees ) select * from t12 where srank <= 2; */witht12as(selectdept_id,employees.emp_name,employees.salary,row_number()over(partitionbyemployees.dept_idorderbyemployees.salarydesc)assrankfromemployees)selectt12.emp_name,t12.salary,dept_namefromt12joindepartmentsont12.dept_id=departments.dept_idwheret12.srank<=2;#13/* 大于公司平均工资 select emp_name,salary,dept_id from employees where salary > (select avg(employees.salary) as savg from employees); */#部门佼佼者selecte.emp_name,e.salary,e.dept_idfromemployees ewheree.salary>(selectavg(salary)fromemployeeswheredept_id=e.dept_id);#14select*,row_number()over(partitionbydept_idorderbysalarydesc)assrank,sum(salary)over(partitionbydept_id)as总和,concat(round(salary/sum(salary)over(partitionbydept_id),2)*100,'%')as占比fromemployees e;#15/*错误写法 where 不允许聚合函数 应该使用子查询 select e.name,e.salary row_number() over (order by salary desc ) as srank from employees e where e.srank between 3 and 5; */select*,row_number()over(orderbysalarydesc)assrankfromemployees;selectt.emp_name,t.salary,t.srankfrom(select*,row_number()over(orderbysalarydesc)assrankfromemployees)astwheret.srankbetween3and5;

卡壳点汇总

题号 出错点 错误类型
8 别名 '排行 缺少右引号 语法错误
9 别名 '排行 缺少右引号 语法错误
10 dense_rank() 没有加 over() 和 order by 语法错误
11 group by 写在 from 前面 语法顺序错误
11 分号放错位置,导致 group by 变成独立语句 语法错误
11 关联条件写错(自己=自己) 逻辑错误
12 误用 group by 取前N名 思路错误
13 子查询中 dept_id 没有用外层别名区分 关联子查询错误
14 row_number() 和 sum() 之间缺少逗号 语法错误
14 over(pa) 没写完 语法错误
14 用 row_number() 去除算百分比 逻辑错误
15 select 中列之间缺少逗号 语法错误
15 where 中直接使用窗口函数别名 执行顺序错误

核心知识点总结

  1. 窗口函数三件套
    sql
    row_number() over (partition by 分组列 order by 排序列 排序方式) – 唯一序号,不并列
    rank() over (order by 排序列 排序方式) – 并列跳号
    dense_rank() over (order by 排序列 排序方式) – 并列不跳号
    函数 工资相同 下一个排名
    row_number() 不并列(分1、2) 3
    rank() 并列(1、1) 3(跳号)
    dense_rank() 并列(1、1) 2(不跳号)

  2. 窗口函数的两大限制
    限制 说明 解决方案
    ❌ 不能在 where 中使用 where 执行在 select 之前,别名还不存在 用子查询或 CTE 包一层再筛选
    ❌ 不能直接用于除法(函数嵌套错误) 用 row_number() 去除没有意义 用 salary 去除

  3. 关联子查询
    sql
    – 比所在部门平均工资高
    select e.*
    from employees e
    where e.salary > (
    select avg(salary)
    from employees
    where dept_id = e.dept_id – 关键:用外层别名关联
    );
    要点:外层一定要起别名,子查询中用这个别名来关联。

  4. CTE 标准模板(取前N名)
    sql
    with 临时表名 as (
    select *,
    row_number() over (partition by 分组列 order by 排序列 desc) as rn
    from 原表
    )
    select *
    from 临时表名
    where rn <= N;

  5. 执行顺序(重要!)
    sql
    from – 1. 确定数据源
    where – 2. 行级筛选(此时还没有窗口函数!)
    group by – 3. 分组
    having – 4. 组级筛选
    select – 5. 选择列(窗口函数在这里生成)
    order by – 6. 排序
    所以:where 中不能引用窗口函数别名,因为窗口函数在 select 阶段才生成。

  6. 逗号规则(老问题)
    sql
    select 列1, – ✅ 后面还有列,加逗号
    列2, – ✅ 后面还有列,加逗号
    列3 – ✅ 最后一项,不加逗号
    from 表;
    换行不等于分隔,逗号才是分隔符!

总结

窗口函数三兄弟,rank 跳号 dense 连,row_number 唯一序;
where 里面不能用,子查询或 CTE 来包;
关联子查询要记牢,外层别名内层用;
逗号分隔最后不加,换行不能代替它。

http://www.cnnetsun.cn/news/3332057.html

相关文章:

  • ElGamal加密算法弱随机数漏洞分析与Python爆破实战
  • MFC应用集成CEF实现C++与JavaScript双向通信实战指南
  • 5分钟快速上手:MediaCrawler多平台数据采集完整指南
  • C++实现大衍求一术:从中国剩余定理到现代代码实践
  • 夏普比率最大化:从理论最优到实盘稳健的工程化落地
  • Code::Blocks 20.03 + LVGL 9.1 模拟器:3步完成Windows环境搭建与Demo运行
  • C与C++栈实现对比:从手动内存管理到模板泛型编程
  • Unity角色动画实战:Mixamo资源整合与Animator系统深度配置指南
  • Hello-Agents:从零构建AI智能体的开源教程与实践指南
  • Unity Tilemap实战:从《星露谷物语》到《空洞骑士》的2D地图构建指南
  • 知识表示方法对比:产生式、框架、语义网络3种方案适用场景解析
  • Subtitle Edit完全指南:从新手到专家的免费字幕编辑解决方案
  • UE4蓝图实现第三人称角色自动寻路:从NavMesh配置到AI移动优化
  • 架构师告别上下文焦虑:面对百万级Token,这套长效记忆方案让Agent真正长脑子
  • Honey Select 2终极增强补丁:一站式解决游戏体验所有痛点
  • 邢台计算机二级冲刺班推荐,短期提分秘诀在这里
  • Pandas数据处理实战地图:从摄入到交付的6阶段操作指南
  • C++内存池性能优化:内存对齐原理与五大关键实践
  • 英雄联盟玩家必备:3分钟解锁League Akari自动化工具包,告别繁琐操作
  • 从内存寻址到游戏操控:使用Cheat Engine逆向分析Windows扫雷
  • 数字功放与微控制器在音频系统升级中的应用
  • UABEA实战指南:Unity资源逆向分析与修改的三大核心方法
  • 深入解析Binary Ninja Python开源原型:从反汇编引擎到逆向工程实践
  • Android Studio 2024 + AGP 7.4.2 配置:5 个关键文件修改与 NDK 版本兼容性实测
  • N皇后问题的遗传算法Python实战:从8到100皇后的工程化实现
  • 模板驱动型文档自动化:从Word快照到规则引擎的范式升级
  • C++共享内存实战:从零构建高性能进程间通信框架
  • 2026年维普AI检测达标指南:维普论文AI率超标4.8元完整处理方案
  • 遗传算法Python实战:N皇后问题从零实现与调优
  • CMU深度学习课程解析:从数学原理到工程实践的完整学习体系