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 窗口函数语法
窗口函数的基本语法:
[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 排名函数实战
排名函数命令:
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;
执行结果:
———- ———— ——– ——-
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 分析函数实战
分析函数命令:
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;
执行结果:
——– ———– ——————- ———— ———– ———–
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;
执行结果:
——– ——————- ———— ———–
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
