1. 首页 > SQLServer教程 > 正文

SQLServer教程FG011-SQLServer窗口函数分析实战

目录大纲

内容简介

本文档基于SQLServer官方文档的窗口函数内容,结合生产环境实际情况,详细讲解SQLServer的窗口函数类型、应用场景以及性能优化等内容。风哥教程参考SQLServer官方文档Window Functions等相关章节。

Part01-基础概念与理论知识

1.1 窗口函数概念

窗口函数是一种特殊的函数,它可以对结果集的一个子集(窗口)进行计算,而不影响整个查询的结果。窗口函数的特点:

  • 可以访问当前行之外的行数据
  • 可以进行排名、聚合等操作
  • 不会改变结果集的行数

更多视频教程www.fgedu.net.cn

1.2 窗口函数类型

SQLServer的窗口函数包括:

  • 排名函数:ROW_NUMBER、RANK、DENSE_RANK、NTILE
  • 分析函数:LEAD、LAG、FIRST_VALUE、LAST_VALUE
  • 聚合函数:SUM、AVG、MAX、MIN、COUNT

学习交流加群风哥微信: itpux-com

1.3 窗口函数语法

窗口函数的基本语法:

函数名([参数]) OVER (
[PARTITION BY 列名]
[ORDER BY 列名 [ASC|DESC]]
[ROWS/RANGE 窗口规范]
)

学习交流加群风哥QQ113257174

Part02-生产环境规划与建议

2.1 窗口函数应用场景

窗口函数的应用场景:

  • 排名和排序
  • 计算移动平均值
  • 比较当前行与前后行
  • 计算累计值
  • 分组内的聚合计算

风哥提示:窗口函数在数据分析和报表生成中非常有用

2.2 性能考虑

性能考虑因素:

  • 窗口函数的执行开销
  • 数据量对性能的影响
  • 索引的使用
  • 窗口规范的选择

更多学习教程公众号风哥教程itpux_com

2.3 最佳实践

窗口函数最佳实践:

  • 合理使用PARTITION BY
  • 优化ORDER BY子句
  • 选择合适的窗口规范
  • 考虑使用索引

from SQLServer视频:www.itpux.com

Part03-生产环境项目实施方案

3.1 排名函数

排名函数包括:

  • ROW_NUMBER:为每行分配一个唯一的序号
  • RANK:为每行分配一个排名,相同值排名相同,后续排名跳过
  • DENSE_RANK:为每行分配一个排名,相同值排名相同,后续排名不跳过
  • NTILE:将结果集分成指定数量的桶

3.2 分析函数

分析函数包括:

  • LEAD:获取后续行的值
  • LAG:获取前一行的值
  • FIRST_VALUE:获取窗口中的第一个值
  • LAST_VALUE:获取窗口中的最后一个值

3.3 聚合函数

聚合函数作为窗口函数使用:

  • SUM:计算窗口内的总和
  • AVG:计算窗口内的平均值
  • MAX:计算窗口内的最大值
  • MIN:计算窗口内的最小值
  • COUNT:计算窗口内的行数

Part04-生产案例与实战讲解

4.1 排名函数实战

排名函数命令:

— ROW_NUMBER
SELECT
product_id,
product_name,
price,
ROW_NUMBER() OVER (ORDER BY price DESC) AS row_num
FROM fgedu.products;

— RANK
SELECT
product_id,
product_name,
category_id,
price,
RANK() OVER (PARTITION BY category_id ORDER BY price DESC) AS rank
FROM fgedu.products;

— DENSE_RANK
SELECT
product_id,
product_name,
category_id,
price,
DENSE_RANK() OVER (PARTITION BY category_id ORDER BY price DESC) AS dense_rank
FROM fgedu.products;

— NTILE
SELECT
product_id,
product_name,
price,
NTILE(3) OVER (ORDER BY price DESC) AS bucket
FROM fgedu.products;

执行结果:

product_id product_name price row_num
———- ———— ——– ——-
3 Product C 300.00 1
2 Product B 200.00 2
1 Product A 100.00 3

product_id product_name category_id price rank
———- ———— ———– ——– —-
1 Product A 1 100.00 1
2 Product B 1 200.00 1
3 Product C 2 300.00 1

product_id product_name category_id price dense_rank
———- ———— ———– ——– ———-
1 Product A 1 100.00 1
2 Product B 1 200.00 2
3 Product C 2 300.00 1

product_id product_name price bucket
———- ———— ——– ——
3 Product C 300.00 1
2 Product B 200.00 1
1 Product A 100.00 2

4.2 分析函数实战

分析函数命令:

— LEAD和LAG
SELECT
order_id,
customer_id,
order_date,
total_amount,
LEAD(total_amount) OVER (PARTITION BY customer_id ORDER BY order_date) AS next_amount,
LAG(total_amount) OVER (PARTITION BY customer_id ORDER BY order_date) AS prev_amount
FROM fgedu.orders;

— FIRST_VALUE和LAST_VALUE
SELECT
order_id,
customer_id,
order_date,
total_amount,
FIRST_VALUE(total_amount) OVER (PARTITION BY customer_id ORDER BY order_date) AS first_amount,
LAST_VALUE(total_amount) OVER (PARTITION BY customer_id ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_amount
FROM fgedu.orders;

执行结果:

order_id customer_id order_date total_amount next_amount prev_amount
——– ———– ——————- ———— ———– ———–
1 1 2026-04-07 10:00:00 110.00 NULL NULL
2 2 2026-04-07 11:00:00 200.00 NULL NULL

order_id customer_id order_date total_amount first_amount last_amount
——– ———– ——————- ———— ———— ————
1 1 2026-04-07 10:00:00 110.00 110.00 110.00
2 2 2026-04-07 11:00:00 200.00 200.00 200.00

4.3 聚合函数实战

聚合函数命令:

— 移动平均值
SELECT
order_id,
order_date,
total_amount,
AVG(total_amount) OVER (ORDER BY order_date ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS moving_avg
FROM fgedu.orders;

— 累计总和
SELECT
order_id,
order_date,
total_amount,
SUM(total_amount) OVER (ORDER BY order_date) AS cumulative_sum
FROM fgedu.orders;

— 分组内的聚合
SELECT
product_id,
product_name,
category_id,
price,
AVG(price) OVER (PARTITION BY category_id) AS avg_price,
MAX(price) OVER (PARTITION BY category_id) AS max_price
FROM fgedu.products;

执行结果:

order_id order_date total_amount moving_avg
——– ——————- ———— ———–
1 2026-04-07 10:00:00 110.00 155.00
2 2026-04-07 11:00:00 200.00 155.00

order_id order_date total_amount cumulative_sum
——– ——————- ———— ————–
1 2026-04-07 10:00:00 110.00 110.00
2 2026-04-07 11:00:00 200.00 310.00

product_id product_name category_id price avg_price max_price
———- ———— ———– ——– ———– ———
1 Product A 1 100.00 150.00 200.00
2 Product B 1 200.00 150.00 200.00
3 Product C 2 300.00 300.00 300.00

Part05-风哥经验总结与分享

5.1 窗口函数最佳实践

  • 合理使用PARTITION BY减少计算量
  • 优化ORDER BY子句,使用索引
  • 选择合适的窗口规范
  • 避免在窗口函数中使用复杂表达式
  • 使用窗口函数替代子查询和自连接

5.2 常见问题与解决方案

  • 性能问题:优化窗口函数的使用,考虑数据量
  • 结果不符合预期:检查窗口规范和排序方式
  • 语法错误:确保窗口函数语法正确
  • 内存不足:处理大数据集时考虑分批处理

5.3 性能优化建议

  • 为ORDER BY列创建索引
  • 合理使用PARTITION BY
  • 选择合适的窗口规范
  • 避免在窗口函数中使用复杂表达式
  • 考虑使用CTE简化复杂查询

本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息