SQL语法进阶篇(二),数据库复杂查询——窗口函数
在学习和实践窗口函数之前,需要准备好工具,以确保能够顺利编写、运行和调试 SQL 语句。这里我选用的是 Kooboo 的SQL数据库在线工具:
1、创建数据表

2、查询数据表

二、 窗口函数(Window Function)
1. 定义与基本原理
     窗口函数是对一组行(称为窗口)执行计算,并为每一行返回一个结果。它不像传统的聚合函数那样将结果集分组为单个行,而是在不改变结果集行数的情况下,为每一行计算一个聚合值。窗口函数通过OVER子句来定义窗口的范围和排序规则。
2. 常见窗口函数类型及用途
核心关键字:
-  PARTITION BY:定义分组窗口。
-  ORDER BY:窗口内排序。
-  ROWS/RANGE:定义窗口范围。
- 聚合窗口函数 - 概念:包括SUM()、AVG()、MIN()、MAX()等传统聚合函数作为窗口函数使用。
- 使用场景:用于计算累计值、移动平均值等。例如,计算每个月的累计销售额,或者计算最近几个月的移动平均销售额。
- 示例:假设有sales表,包含month和sales_amount字段,要计算每个月的累计销售额,可使用以下查询:SELECT month,sales_amount,SUM(sales_amount) OVER (ORDER BY month) AS cumulative_sales FROM sales;-- OVER (ORDER BY month) 表示按照 month 列进行排序,窗口的范围是从结果集的第一行到当前行 -- AS cumulative_sales:这是为计算结果指定的别名,方便在结果集中引用
 
- 概念:包括
- 排名窗口函数 - 概念:包括RANK()、DENSE_RANK()、ROW_NUMBER()等,用于为结果集中的行分配排名。
- 使用场景:对数据进行排名,例如对员工的工资进行排名,找出工资最高的前几名员工。
- 示例: SELECT month,sales_amount,RANK() OVER (ORDER BY sales_amount DESC) AS sales_rank FROM sales;-- RANK()函数会根据销售额降序排列为每一行分配排名 -- 如果有相同的销售额,会出现并列排名,且下一个排名会跳过相应的序号
 
- 概念:包括
- 分析窗口函数 - 概念:如LAG()、LEAD()、FIRST_VALUE()、LAST_VALUE()等,用于获取当前行前后的数据或窗口内的第一个、最后一个值。
- 使用场景:分析数据的变化趋势,例如比较相邻月份的销售额变化。
- 示例: SELECT month,sales_amount,LAG(sales_amount) OVER (ORDER BY month) AS prev_month_sales FROM sales;-- LAG(sales_amount) OVER (ORDER BY month)会返回当前行上一行的销售额,方便比较相邻月份的销售情况。
 
- 概念:如
3. 窗口范围(Frame)的本质
     窗口函数在ORDER BY排序后,通过 ** 窗口范围(Frame)** 定义参与计算的行集合。它决定了 “当前行” 的上下边界,使得聚合函数(如SUM、AVG)或排名函数(如RANK)能在特定范围内计算。
核心作用:精确控制窗口函数的计算范围,实现累计值、滑动平均、移动统计等复杂分析。
-  ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW:从第一行到当前行。
-  RANGE BETWEEN INTERVAL '7' DAY PRECEDING AND CURRENT ROW:按时间范围(如7天滑动窗口)。
4. 默认窗口范围:隐式的ROWS模式
若未显式声明ROWS或RANGE,窗口函数默认使用:
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW即从排序后的第一行到当前行,形成一个累计窗口。
 示例(等价写法):
-- 隐式默认写法
SUM(sales_amount) OVER (ORDER BY month)  -- 显式声明写法
SUM(sales_amount) OVER (ORDER BY month ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)