Oracle 开窗函数

在 Oracle 数据库中,开窗函数(Window Functions)是一类非常强大的 SQL 函数,用于在结果集的"窗口"上执行计算。这些窗口函数允许你在查询的每一行上执行聚合操作(如求和、平均、计数等),同时保留原始行的详细数据。

以下是一些常见的 Oracle 开窗函数及其用法:

1. ROW_NUMBER()

为结果集中的每一行分配一个唯一的序号。

sql 复制代码
SELECT 
employee_id, 
department_id, 
salary, 
ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rank_in_dept 
FROM 
employees;

2. RANK()

类似于 ROW_NUMBER(),但如果有相同的值,它们会共享相同的排名,并且后续排名会跳过。

sql 复制代码
SELECT 
employee_id, 
department_id, 
salary, 
RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rank_in_dept 
FROM 
employees;

3. DENSE_RANK()

类似于 RANK(),但后续排名不会跳过。

sql 复制代码
SELECT 
employee_id, 
department_id, 
salary, 
DENSE_RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS dense_rank_in_dept 
FROM 
employees;

4. NTILE(n)

将结果集划分为 n 个桶,并为每一行分配一个桶号。

sql 复制代码
SELECT 
employee_id, 
department_id, 
salary, 
NTILE(4) OVER (PARTITION BY department_id ORDER BY salary DESC) AS quartile 
FROM 
employees;

5. LAG() 和 LEAD()

用于访问结果集中当前行的前一行或后一行的数据。

sql 复制代码
SELECT 
employee_id, 
department_id, 
salary, 
LAG(salary, 1) OVER (PARTITION BY department_id ORDER BY salary) AS prev_salary, 
LEAD(salary, 1) OVER (PARTITION BY department_id ORDER BY salary) AS next_salary 
FROM 
employees;

6. FIRST_VALUE() 和 LAST_VALUE()

返回窗口框架中的第一行或最后一行的值。

sql 复制代码
SELECT

employee_id,

department_id,

salary,

FIRST_VALUE(salary) OVER (PARTITION BY department_id ORDER BY salary RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS first_salary_in_dept,

LAST_VALUE(salary) OVER (PARTITION BY department_id ORDER BY salary RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_salary_in_dept

FROM

employees;

7. SUM(), AVG(), MIN(), MAX() 等聚合函数

在窗口上执行常见的聚合操作。

sql 复制代码
SELECT 
employee_id, 
department_id, 
salary, 
SUM(salary) OVER (PARTITION BY department_id ORDER BY salary RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS cumulative_salary 
FROM 
employees;

窗口子句(Window Clause)

在开窗函数中,OVER 子句用于定义窗口的分区和排序。PARTITION BY 子句用于将结果集划分为分区,ORDER BY 子句用于定义每个分区内的排序顺序。

sql 复制代码
OVER ( 
[PARTITION BY partition_expression, ...] 
[ORDER BY sort_expression [ASC|DESC], ...] 
[ROWS|RANGE BETWEEN frame_start AND frame_end] 
)
  • PARTITION BY:将结果集划分为多个分区,每个分区独立计算。
  • ORDER BY:定义每个分区内的排序顺序。
  • ROWSRANGE:定义窗口框架(frame),即窗口内包含的行范围。

示例:综合使用

sql 复制代码
SELECT 
employee_id, 
department_id, 
salary, 
ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rank_in_dept, 
SUM(salary) OVER (PARTITION BY department_id ORDER BY salary RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS cumulative_salary 
FROM 
employees;

以上示例展示了如何使用多个开窗函数,并结合 PARTITION BYORDER BY 子句进行复杂查询。

相关推荐
直有两条腿18 分钟前
【数据迁移】HBase Bulkload批量加载原理
大数据·数据库·hbase
言之。40 分钟前
ClickHouse 数据更新策略深度解析:突变操作与最佳实践
服务器·数据库·clickhouse
白衣鸽子2 小时前
数据库高可用设计的灵魂抉择:CAP权衡
数据库·后端
DokiDoki之父3 小时前
Mybatis—入门 & (配置)SQL提示和日志输出
数据库·sql·mybatis
TDengine (老段)4 小时前
TDengine 数据函数 LN 用户手册
大数据·数据库·物联网·时序数据库·tdengine·涛思数据
机灵猫4 小时前
Redis 在订单系统中的实战应用:防重、限流与库存扣减
数据库·redis·缓存
木易2.04 小时前
从零构建RAG知识库管理系统(二)
数据库·oracle
程序新视界4 小时前
什么是MySQL JOIN查询的驱动表和被驱动表?
数据库·后端·mysql
lingggggaaaa5 小时前
小迪安全v2023学习笔记(一百三十四讲)—— Windows权限提升篇&数据库篇&MySQL&MSSQL&Oracle&自动化项目
java·数据库·windows·笔记·学习·安全·网络安全
小光学长5 小时前
基于Vue的保护动物信息管理系统r7zl6b88 (程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
前端·数据库·vue.js