MYSQL 排序函数 RANK 函数 和 DENSE_RANK() 函数 185. 部门工资前三高的所有员工

题目:

表: Employee

+--------------+---------+
| Column Name  | Type    |
+--------------+---------+
| id           | int     |
| name         | varchar |
| salary       | int     |
| departmentId | int     |
+--------------+---------+
Id是该表的主键列。
departmentId是Department表中ID的外键。
该表的每一行都表示员工的ID、姓名和工资。它还包含了他们部门的ID。

表: Department

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| id          | int     |
| name        | varchar |
+-------------+---------+
Id是该表的主键列。
该表的每一行表示部门ID和部门名。

公司的主管们感兴趣的是公司每个部门中谁赚的钱最多。一个部门的 高收入者 是指一个员工的工资在该部门的 不同 工资中 排名前三 。

编写一个SQL查询,找出每个部门中 收入高的员工 。

以 任意顺序 返回结果表。

查询结果格式如下所示。

示例 1:

输入: 
Employee 表:
+----+-------+--------+--------------+
| id | name  | salary | departmentId |
+----+-------+--------+--------------+
| 1  | Joe   | 85000  | 1            |
| 2  | Henry | 80000  | 2            |
| 3  | Sam   | 60000  | 2            |
| 4  | Max   | 90000  | 1            |
| 5  | Janet | 69000  | 1            |
| 6  | Randy | 85000  | 1            |
| 7  | Will  | 70000  | 1            |
+----+-------+--------+--------------+
Department  表:
+----+-------+
| id | name  |
+----+-------+
| 1  | IT    |
| 2  | Sales |
+----+-------+
输出: 
+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| IT         | Max      | 90000  |
| IT         | Joe      | 85000  |
| IT         | Randy    | 85000  |
| IT         | Will     | 70000  |
| Sales      | Henry    | 80000  |
| Sales      | Sam      | 60000  |
+------------+----------+--------+
解释:
在IT部门:
- Max的工资最高
- 兰迪和乔都赚取第二高的独特的薪水
- 威尔的薪水是第三高的

在销售部:
- 亨利的工资最高
- 山姆的薪水第二高
- 没有第三高的工资,因为只有两名员工

解题思路:

RANK()

函数为结果集的分区中的每一行分配一个排名。行的等级由一加上前面的等级数指定。意思是排名会跳,因为有并列排名

以下显示了RANK()函数的语法:

RANK() OVER (
    PARTITION BY <expression>[{,<expression>...}]
    ORDER BY <expression> [ASC|DESC], [{,<expression>...}]
)

在这个语法中:

  • 首先,PARTITION BY子句将结果集划分为分区。RANK()功能在分区内执行,并在跨越分区边界时重新初始化。
  • 其次,ORDER BY子句按一个或多个列或表达式对分区内的行进行排序。

DENSE_RANK()排名不会跳,没有间隙 

方法:

先给表加上排名,由于不区分并列,所以用DENSE_RANK():并且需要按照部门来分区,即每个部门的排名重新计算

select d.Name as Department, e.Name as Employee, e.Salary as Salary, 
dense_rank() over ( partition by DepartmentId order by Salary desc) as rk
from Employee as e, Department as d
where e.DepartmentId = d.Id

之后再取出每个部门排名前三的

select Department, Employee, Salary
from (
    select d.Name as Department, e.Name as Employee, e.Salary as Salary, 
dense_rank() over ( partition by DepartmentId order by Salary desc) as rk
    from Employee as e, Department as d
    where e.DepartmentId = d.Id
) m
where rk <= 3;

### 回答1: MySQL中的DENSE_RANK函数是一种排名函数,用于计算结果集中每行的排名。与RANK函数不同的是,DENSE_RANK函数不会跳过排名相同的行,而是将它们视为同一排名,并为它们分配相同的排名值。DENSE_RANK函数的语法如下: DENSE_RANK() OVER ( [PARTITION BY partition_expression, ... [n]] ORDER BY sort_expression [ASC | DESC], ... [n] ) 其中,PARTITION BY子句用于指定分区列,ORDER BY子句用于指定排序列。DENSE_RANK函数返回一个整数值,表示当行的排名。 ### 回答2: MySQL中的DENSE_RANK函数是常用的窗口函数之一。它可以在给定排序条件的情况下,返回一个排名值列,其中相同值具有相同的排名值,而下一个不同的值将具有一个新的排名值。 DENSE_RANK函数的语法如下: ``` DENSE_RANK() OVER ( [PARTITION BY partition_expression, ... ] ORDER BY sort_expression [ASC|DESC], ... ) ``` 其中,PARTITION BY子句是可选的,可以定义一个或多个分区表达式,这些表达式将数据集分为多个分区进行排名。ORDER BY子句是必需的,用于指定排序条件,可以指定一个或多个排序表达式,以及一个可选的排序方向(ASC或DESC)。 DENSE_RANK函数返回的值是排名值。相同的数据将具有相同的排名值,而数据集中不同的下一个值将具有一个新的排名值。例如,如果有三个人的成绩如下:90、90、85,它们的排名值将是1、1、2,因为有两个人获得了相同的最高分。 需要注意的是,DENSE_RANK是一个窗口函数,它需要使用OVER子句进行使用。窗口函数可以对整个数据集或数据集的子集进行计算, DENSE_RANK 需要进行排序,因此需要将排序条件作为子句的一部分。另外,DENSE_RANK只能在MySQL8.0版本以上使用。 总之,DENSE_RANK函数是一个非常有用的函数,可以轻松处理需要对数据进行排名的情况。它可以帮助我们更好地理解数据集,找到最高或最低的值,以及在数据集中确定某个值的相对位置。 ### 回答3: MySQL中的DENSE_RANK(密集排名)函数是一种用来对查询结果的行进行排名的窗口函数。与传统的RANK函数不同的是,DENSE_RANK函数不会跳过相同排名的行,而是给相同排名的行赋相同的排名值。 语法: DENSE_RANK() OVER (ORDER BY column_name) 其中,column_name是用于排序的列名。 举个例子,假设有如下一张学生成绩表: | name | subject | score | |------|---------|-------| | Tom | Math | 80 | | Tom | English | 70 | | Jack | Math | 90 | | Jack | English | 80 | | Lucy | Math | 70 | | Lucy | English | 90 | | Ben | Math | 80 | | Ben | English | 80 | 如果我们想对每个学生的总成绩排名,并且让排名相同的学生排名值相同,可以使用以下查询: SELECT name, SUM(score) as total_score, DENSE_RANK() OVER (ORDER BY SUM(score) DESC) as rank FROM table_name GROUP BY name ORDER BY rank 输出结果如下: | name | total_score | rank | |------|-------------|------| | Jack | 170 | 1 | | Ben | 160 | 2 | | Tom | 150 | 3 | | Lucy | 160 | 2 | 可以看到,在排名第二名的BenLucy中,由于成绩相同,它们的排名值也相同。 总之,DENSE_RANK函数是一种非常实用的函数,可以在需要对排名值相同的行进行特定操作时使用。它与其他窗口函数一起,为我们提供了更大的灵活性功能性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值