SQL 窗口函数 - 教程
语法解析
sql
Apply
ROW_NUMBER() OVER (PARTITION BY fund_code ORDER BY trade_date DESC) as rn
各部分含义:
- ROW_NUMBER() - 窗口函数,为每一行分配一个唯一的序号
- OVER - 定义窗口函数的计算范围
- PARTITION BY fund_code - 按 fund_code 分组
- ORDER BY trade_date DESC - 在每个分组内按 trade_date 降序排列
- as rn - 给结果列起名为 rn
工作原理
假设原始数据:
text
Apply
fund_code trade_date nav
MF000111 2024-01-15 1.25
MF000111 2024-01-16 1.26
MF000111 2024-01-17 1.27
MF000975 2024-01-15 2.10
MF000975 2024-01-16 2.11
执行窗口函数后:
text
Apply
fund_code trade_date nav rn
MF000111 2024-01-17 1.27 1 ← 最新日期,rn=1
MF000111 2024-01-16 1.26 2
MF000111 2024-01-15 1.25 3
MF000975 2024-01-16 2.11 1 ← 最新日期,rn=1
MF000975 2024-01-15 2.10 2
完整示例
sql
Apply
SELECT
fund_code,
trade_date,
nav,
ROW_NUMBER() OVER (PARTITION BY fund_code ORDER BY trade_date DESC) as rn
FROM fund
WHERE fund_code IN ('MF000111', 'MF000975')
结果:
text
Apply
fund_code trade_date nav rn
MF000111 2024-01-17 1.27 1
MF000111 2024-01-16 1.26 2
MF000111 2024-01-15 1.25 3
MF000975 2024-01-16 2.11 1
MF000975 2024-01-15 2.10 2
然后通过 WHERE rn = 1 筛选出每个 fund_code 的最新记录:
text
Apply
fund_code trade_date nav rn
MF000111 2024-01-17 1.27 1
MF000975 2024-01-16 2.11 1
其他窗口函数对比
sql
Apply
-- ROW_NUMBER(): 唯一序号
ROW_NUMBER() OVER (PARTITION BY fund_code ORDER BY trade_date DESC)
-- RANK(): 相同值相同排名,跳过序号
RANK() OVER (PARTITION BY fund_code ORDER BY trade_date DESC)
-- DENSE_RANK(): 相同值相同排名,不跳过序号
DENSE_RANK() OVER (PARTITION BY fund_code ORDER BY trade_date DESC)
为什么用 ROW_NUMBER()
- 唯一的就是唯一性:每个分组内的序号都
- 简单筛选:WHERE rn = 1 就能获取每组的第一条记录
- 性能好:比子查询更高效
这样就能准确获取每个 fund_code 对应的最新 trade_date 的完整记录。