sql窗口函数
窗口函数是一个统称(也叫分析函数),它并不是一个具体的函数,而是一种 “函数使用方式”—— 把普通的聚合函数、排名函数等放到 OVER() 子句中,就变成了窗口函数。
窗口函数的结构是:函数名() OVER (窗口子句),其中函数名可以替换成多种类型的函数,OVER() 子句定义 “计算窗口”(分组、排序、范围)
1.聚合类窗口函数(最常用)
基础聚合函数 | 窗口函数用法(示例) | 作用 |
SUM() | SUM(profit) OVER (PARTITION BY shop_id ORDER BY profit_date) | 分组累计求和(如累计利润) |
AVG() | AVG(score) OVER (PARTITION BY class ORDER BY exam_date) | 分组滚动求平均(如班级平均分趋势) |
MAX() / MIN() | MAX(gpa) OVER (PARTITION BY university) | 分组内取极值(如每个学校的最高 GPA) |
COUNT() | COUNT(*) OVER (PARTITION BY dept) | 分组内统计行数(如每个部门的人数) |
2.排名类窗口函数(仅限作为窗口)
这类函数只能作为窗口函数使用,无法单独用,核心用于生成排名、序号。
排名函数 | 用法示例 | 作用 |
ROW_NUMBER() | ROW_NUMBER() OVER (PARTITION BY university ORDER BY gpa DESC) | 分组内连续排名(1,2,3…,无并列) |
RANK() | RANK() OVER (ORDER BY score DESC) | 跳跃排名(1,2,2,4…,并列会跳过序号) |
DENSE_RANK() | DENSE_RANK() OVER (ORDER BY score DESC) | 连续排名(1,2,2,3…,并列不跳过序号) |
NTILE(n) | NTILE(4) OVER (ORDER BY sales) | 分组内分桶(如把销售额分成 4 个等级) |
3.偏移类窗口函数(仅限作为窗口函数)
偏移函数 | 用法示例 | 作用 |
LAG() | LAG(profit, 1) OVER (ORDER BY profit_date) | 获取上 1 行的利润(计算日环比) |
LEAD() | LEAD(profit, 7) OVER (ORDER BY profit_date) | 获取下 7 行的利润(计算周同比) |
FIRST_VALUE() | FIRST_VALUE(gpa) OVER (PARTITION BY university ORDER BY gpa) | 分组内第一行的 GPA(最低 GPA) |
LAST_VALUE() | LAST_VALUE(gpa) OVER (PARTITION BY university ORDER BY gpa) | 分组内最后一行的 GPA(最高 GPA) |
简单记:只要把函数放到 OVER() 里,它就具备了 “窗口分析” 的能力,这也是窗口函数灵活的核心原因。
补充:聚合函数
函数 | 作用 | 示例(基于 user_profile 表) |
COUNT() | 统计行数(非 NULL 值的数量) | SELECT COUNT(device_id) AS student_count FROM user_profile GROUP BY university; (统计每个学校的学生数) |
SUM() | 计算数值字段的总和 | SELECT SUM(score) AS total_score FROM exam GROUP BY class; (计算每个班级的总分) |
AVG() | 计算数值字段的平均值 | SELECT AVG(gpa) AS avg_gpa FROM user_profile GROUP BY university; (计算每个学校的平均 GPA) |
MAX() | 取数值 / 字符串 / 日期字段的最大值 | SELECT MAX(gpa) AS max_gpa FROM user_profile GROUP BY university; (取每个学校的最高 GPA) |
MIN() | 取数值 / 字符串 / 日期字段的最小值 | SELECT MIN(gpa) AS min_gpa FROM user_profile GROUP BY university; (取每个学校的最低 GPA) |