SQL开窗函数之排序函数

开窗函数

当我们需要进行一些比较复杂的子查询时,聚合函数就会非常的麻烦,因此可以使用开窗函数进行分组再运用函数查询。窗口函数既可以显示聚集前的数据,也可以显示聚集后的数据,可以在同一行中返回基础行的列值和聚合后的结果列

常见运用场景: 对班里同学成绩进行排序

常见的窗口函数
SQL开窗函数之排序函数_第1张图片

开窗函数基本形式

func_name(<parameter>) 
OVER(
[PARTITION BY <part_by_condition>] 
[ORDER BY <order_by_list> ASC|DESC]
[rows between ?? And ??]
)

具体字段的解释看我的上一篇:SQL开窗函数之基本用法和聚合函数

排序函数

排序函数主要有三种

  • row_number(): 顺序排序——1,2,3
  • rank(): 并列排序,相同的值为同一序号,跳过重复的序号——1,1,3
  • dense_rank(): 并列排序,相同的值为同一序号,不跳过重复序号——1,1,2

e.g. Sales表
SQL开窗函数之排序函数_第2张图片

  • 直接排序
select *, 
row_number() over(order by sales desc) as row_num,
rank() over(order by sales desc) as rank_num,
dense_rank() over(order by sales desc) as dense_num
from Sales;

SQL开窗函数之排序函数_第3张图片

  • 分组排序
select *, 
row_number() over(partition by month(idate) order by sales desc) as row_num,
rank() over(partition by month(idate) order by sales desc) as rank_num,
dense_rank() over(partition by month(idate) order by sales desc) as dense_num
from Sales;

SQL开窗函数之排序函数_第4张图片

具体实例:leetcode: 184. 部门工资最高的员工

Employee 表
+--------------+---------+
| 列名          | 类型    |
+--------------+---------+
| id           | int     |
| name         | varchar |
| salary       | int     |
| departmentId | int     |
+--------------+---------+
id是此表的主键列。
departmentId是Department表中ID的外键。
此表的每一行都表示员工的ID、姓名和工资。它还包含他们所在部门的ID。

Department 表
+-------------+---------+
| 列名         | 类型    |
+-------------+---------+
| id          | int     |
| name        | varchar |
+-------------+---------+
id是此表的主键列。
此表的每一行都表示一个部门的ID及其名称。

示例:
输入:
Employee 表:
+----+-------+--------+--------------+
| id | name  | salary | departmentId |
+----+-------+--------+--------------+
| 1  | Joe   | 70000  | 1            |
| 2  | Jim   | 90000  | 1            |
| 3  | Henry | 80000  | 2            |
| 4  | Sam   | 60000  | 2            |
| 5  | Max   | 90000  | 1            |
+----+-------+--------+--------------+
Department 表:
+----+-------+
| id | name  |
+----+-------+
| 1  | IT    |
| 2  | Sales |
+----+-------+
输出:
+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| IT         | Jim      | 90000  |
| Sales      | Henry    | 80000  |
| IT         | Max      | 90000  |
+------------+----------+--------+
解释:Max 和 Jim 在 IT 部门的工资都是最高的,Henry 在销售部的工资最高。

答案

-- 使用窗口函数的方式
with a as(
    select name, salary, departmentId, rank() over(partition by departmentId order by salary desc) as cnt from Employee
)
select d.name as Department, a.name as Employee, a.salary as Salary from a 
left join Department as d
on a.departmentId = d.id
where a.cnt = 1

你可能感兴趣的:(SQL,sql,数据库)