1 概述
- 分析函数: 专门用来解决复杂统计报表需求的功能强大的函数
- 开窗函数 over(): 指定函数所能影响的窗口范围
2 语法
function() over(
[partition by ...]
[order by ...]
[windowing-clause]
)
如:
max() over(partition by t.id order by t.name) m
row_number() over(partition by t.id order by t.name) rn
语法解释:
1. function():对窗口中的数据进行操作
(1) 聚合函数
sum(): 求和
min(): 最小值
max(): 最大值
avg(): 平均值
count(): 条数
(2) 排名函数
row_number(): 连续排序,如:1 2 3 4
rank() : 跳跃排序,如:1 2 2 4
dense_rank(): 密集排序,如:1 2 2 3
2. over:关键字,用于识别 分析函数
3. over() 中的 '可选子句'
(1) partition by ...:分区子句
(2) order by ... :排序子句
(3) windowing-clause:窗口子句
语法:order by 字段名 range|rows between 边界1 and 边界2
range:按照 '值' 的范围进行范围的定义
rows :按照 '行' 的范围进行范围的定义
区别:当 '值相同' 时,如依次累加下列值: 100, 200, 200, 300
range rows
第一行 100 100
第二行 500 300 (因为 第二行 和 第三行 '值相同')
第三行 500 500
第四行 800 800
边界取值范围:
current row:当前行
n preceding:前 N 行
n following:后 N 行
unbounded preceding:之前所有
unbounded following:之后所有
3 示例
SELECT t.*
FROM scott.emp t
ORDER BY t.hiredate;
示例1:获取第一位入职的员工信息:
SELECT tt.*
FROM (SELECT row_number() over(ORDER BY t.hiredate) rn,
t.*
FROM scott.emp t) tt
WHERE tt.rn = 1;
示例2:获取每个部门第一位入职的员工信息:
SELECT tt.*
FROM (SELECT row_number() OVER(PARTITION BY t.deptno ORDER BY t.hiredate) rn,
t.*
FROM scott.emp t) tt
WHERE tt.rn = 1;
示例3:获取人员信息 + 每个部门的人数:
SELECT COUNT(*) over(PARTITION BY t.deptno) c,
t.*
FROM scott.emp t;
示例4:获取人员信息 + 累计工资求和:
SELECT SUM(t.sal) over(ORDER BY t.sal rows BETWEEN unbounded preceding AND CURRENT ROW) 到当前行工资求和_rows,
SUM(t.sal) over(ORDER BY t.sal range BETWEEN unbounded preceding AND CURRENT ROW) 到当前行工资求和_range,
t.sal,
t.*
FROM scott.emp t;
4 扩展
1. '第一个' | '最后一个' 值
first_value(字段) over(partition by ... order by ...)
last_value(字段) over(partition by ... order by ...)
-- 理解:range BETWEEN unbounded preceding AND CURRENT ROW
2. '上一个' | '下一个' 值
lag(字段) over(partition by ... order by ...)
lead(字段) over(partition by ... order by ...)