题解 | 查找最晚入职员工的所有信息
查找最晚入职员工的所有信息
https://www.nowcoder.com/practice/218ae58dfdcd4af195fff264e062138f
select emp_no,birth_date,first_name,last_name,gender,hire_date from (select emp_no,birth_date,first_name,last_name,gender,hire_date, dense_rank() over (order by hire_date desc as drk from employees)x where drk=1
这是一道基础的sql入门题,其中核心知识点包括:
1.窗口函数的应用-----解决排序问题 即如何找到最晚入职员工的信息 -------->窗口函数排序相关--------->三个函数-------->需要了解三个函数的不同点
| 行号排序 | 连续不重复 1,2,3,4(同分也不并列) |
| 跳跃排名 | 并列同名,跳过名次 1,1,3,4 |
| 连续排名 | 并列同名,不跳过 1,1,2,3 |
了解上述题目的意图想要找到最晚入职的员工,所以其实它并列同名才是我想要的全部信息,反而是“同分也不并列”会让我缺少一部分信息,其次就是是否需要跳过名次对这道题来说无所谓,所以剩余两个函数RANK(),DENSE_RANK()都可以用
1.1函数详解部分固定用法
排序函数() OVER (
PARTITION BY 分组字段 -- 可选:按某个字段分组排名(如按班级、分类)
ORDER BY 排序字段 DESC/ASC -- 必选:按哪个字段排序,DESC=降序,ASC=升序
) AS 别名
注意在这个过程中我们需要知道“窗口函数的计算发生在 WHERE 子句执行之后”即"WHERE 先执行 → 过滤数据窗口函数后执行 → 给剩下的数据排名" 这个规则本质就是 SQL 的执行顺序决定的,没有任何例外 所以 就注定了代码的写法不能这样写
select emp_no,birth_date,first_name,last_name,gender,hire_date,
dense_rank() over (order by hire_date desc ) as drk
from employees
where drk=1-----窗口函数的别名绝对不能用在 WHERE 里
1.2完整的sql执行顺序
1. FROM → 2. WHERE → 3. GROUP BY → 4. HAVING → 5. SELECT → 6. ORDER BY
根据执行顺序,只有在 SELECT 之后执行的子句,才能使用窗口函数的别名:
WHERE | 第 2 步 | ❌ 绝对不能 | 别名还未生成 |
GROUP BY | 第 3 步 | ❌ 不能 | 别名还未生成 |
HAVING | 第 4 步 | ✅ 可以 | 晚于 SELECT 执行 |
ORDER BY | 第 6 步 | ✅ 可以 | 最后执行,别名已生成 |
1.3延伸知识点 ------转化函数
把日期类型的yyyy-mm-dd改写成yyyymmdd字符串的这种类型
(1)DATE_FORMAT(日期字段, '%Y%m%d')------------------------- MySQL / MariaDB
(2)TO_CHAR(日期字段, 'YYYYMMDD')-----------------------------Oracle
(3)CONVERT(VARCHAR, 日期字段, 112)---------------------------SQL Server
(它是 SQL Server 内置的 日期样式编号(style),含义固定:112 = 输出格式:yyyymmdd)
常用格式代号你可以一起记
最常用的就这几个,一眼看懂:
101→mm/dd/yyyy103→dd/mm/yyyy111→yyyy/mm/dd112→yyyymmdd(你现在要用的)120→yyyy-mm-dd hh:mi:ss(标准时间)23→yyyy-mm-dd(纯日期带横杠)
注意:
| 两位年份 | 26 |
| 四位年份 | 2026 |
两个完整格式对比
%y%m%d(两位年)→ 260413
%Y%m%d(四位年)→ 20260413
核心区别:年份显示位数不同。
注意:永远不要把日期转成字符串再排序!数据库会用真正的日期规则比较,永远不会错
因为字符串排序 ≠ 日期排序
order by hire_date desc 数据库会用真正的日期规则比较,永远不会错。
本期延伸知识点已讲完
