【SQL201】题解 | 查找入职员工时间升序排名的情况下的倒数第三的员工所有信息

查找入职员工时间升序排名的情况下的倒数第三的员工所有信息

https://www.nowcoder.com/practice/ec1ca44c62c14ceb990c3c40def1ec6c

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 rk from employees) e where rk = 3 order by emp_no asc; 

这题比较难,还是看了官方题解之后才会的。这道题目的难点在于排名为3的员工数量可能不只有一个。如果使用distinct去重,意思是先找到某个特定的入职日期。之后,如果表中有入职日期列等于这个特定的入职日期的,就取出他的员工信息。

step1: 找到某个特定的入职日期

SELECT hire_date FROM emloyees ORDER BY (SELECT DISTINCT hire_date FROM emloyees) limit 2,1;

step2: 如果表中有入职日期列等于这个特定的入职日期的,就取出他的员工信息

SELECT * FROM emloyees WHERE hire_date = (SELECT hire_date FROM emloyees ORDER BY (SELECT DISTINCT hire_date FROM emloyees) limit 2,1);

但是上述解法是错误的,在线编辑器上运行会报语法错误。

所以选择官方解法:

step1:使用DENSE_RANK()窗口函数进行包含重复排名的排序,也就是有重复的序号。排序是按照入职日期降序排列,建立一个包含重复排名列rk的派生表或者说是临时表。【注意:临时表(在这里是由子查询生成的派生表)只在当前查询执行期间存在。执行完查询后,临时表会被自动释放,不再占用任何资源。具体而言,派生表并不是一个实际的物理表,而是一个内存中的临时结构。它只在执行该查询的生命周期内存在,在查询执行完后就会被销毁。

SELECT emp_no, birth_date, first_name, last_name, gender, hire_date, DENSE_RANK() over(ORDER BY hire_date DESC) as rk FROM employees
# 建立一个包含重复排名列rk的派生表或者说是临时表

overOVER 是窗口函数的一个关键字,用于指定窗口函数的计算范围和排序规则。它告诉 SQL 查询如何在结果集中应用窗口函数,并确定在哪些行之间进行计算。

OVER (ORDER BY hire_date DESC) 告诉 SQL 排序数据时使用 hire_date 字段按降序(最新日期在前)进行排序。在应用窗口函数(例如 RANK()DENSE_RANK() 等)时,排序决定了每个数据行的计算顺序。

rk:表示 dense_rank() 计算出的排名。如果没有使用 as rk,列名将是一个默认的名称(例如 dense_rank()),而 as rk 是让查询结果更简洁、易于理解的方式。

step2:从派生表中进行外表查询,外表查询的语法如下:

SELECT column1, column2, ...
FROM (
    SELECT sub_column1, sub_column2, ...
    FROM table_name
    WHERE condition
    ORDER BY column
) AS subquery_alias
WHERE external_condition;

SQL 允许在为子查询或表指定别名时省略 AS 关键字,直接写空格和别名;

在本题中是将之前子查询建立的临时表命名为e,然后从表e中取出排名为3的所有员工信息。

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 rk FROM employees) e where rk = 3 order by emp_no asc;

注意外表查询员工信息的时候不能写*,先执行完where rk = 3找到排名为3的所有员工,order by emp_no asc是将所有排名为3的员工按照emp_no员工编号进行升序排列。

完结

SQL学习专栏 文章被收录于专栏

发个sql学习和实践的小记录

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务