开窗函数的详细的介绍

开窗函数介绍使用

开窗函数格式

开窗函数格式 :  
    方式一 :
       
select ... 
     
  聚合函数|排序函数 over(partition by 分组字段名 order by 排序字段名 asc|desc)“添加别名处”
        from 表名;
  
 "默认省略rows between unbounded preceding and current row 从第一行到当前行"
    方式二 :
       
select ... 
       
聚合函数|排序函数 over(partition by 分组字段名 order by 排序字段名 asc|desc rows|range between 起始位置 and 结束位置)“添加别名处”
         from 表名;

聚合函数

聚合开窗函数 : max : 最大值
                         min : 最小值
                         avg : 平均值
                         sum : 相加总值
                         count(1) | count(*) : 计算行数,包括null值
                         count(列名) : 计算行数,不包含null值

排序开窗函数

 排序开窗函数 : row_number  dense_rank  rank
                          row_number: 巧记: 1234   特点: 唯一且连续
                          dense_rank: 巧记: 1223   特点: 并列且连续
                          rank   : 巧记: 1224   特点: 并列不连续

开窗函数控制范围

 开窗函数控制范围: rows|range between xxx and xxx
                                         - unbounded: 无界限
                                       
 - x preceding:往前x行
                                         - x following:往后x行
                
                                         
- unbounded preceding :表示从前面的起点  第一行
                                         - unbounded following :表示到后面的终点  最后一行   
                   
                                          
- current row:当前行

rows 和 range 的区别

测试数据准备

-- 以下操作是在Oracle中进行
-- 数据准备

-- 创建表
CREATE TABLE test(
  video_id number(10),
  dt date,
  if_follow number(10)
);

-- 插入数据
INSERT INTO test VALUES (2001, to_date('2021-09-24','yyyy-mm-dd'), 1);
INSERT INTO test VALUES (2001, to_date('2021-10-03','yyyy-mm-dd'), 9);
INSERT INTO test VALUES (2001, to_date('2021-10-02','yyyy-mm-dd'), 2);
INSERT INTO test VALUES (2001, to_date('2021-10-01','yyyy-mm-dd'), 6);
INSERT INTO test VALUES (2002, to_date('2021-09-25','yyyy-mm-dd'), 1);
INSERT INTO test VALUES (2002, to_date('2021-09-25','yyyy-mm-dd'), 1);
INSERT INTO test VALUES (2002, to_date('2021-09-26','yyyy-mm-dd'), 6);
INSERT INTO test VALUES (2002, to_date('2021-09-27','yyyy-mm-dd'), 1);
INSERT INTO test VALUES (2002, to_date('2021-09-28','yyyy-mm-dd'), 1);
INSERT INTO test VALUES (2002, to_date('2021-09-29','yyyy-mm-dd'), 8);
INSERT INTO test VALUES (2002, to_date('2021-09-30','yyyy-mm-dd'), 7);
INSERT INTO test VALUES (2002, to_date('2021-10-01','yyyy-mm-dd'), 1);
INSERT INTO test VALUES (2002, to_date('2021-10-02','yyyy-mm-dd'), 9);
INSERT INTO test VALUES (2002, to_date('2021-10-03','yyyy-mm-dd'), 1);

-- 提交数据
commit;
rows 是取范围行的值
select
    video_id,
    dt,
    sum(if_follow) over (partition by video_id order by if_follow rows between unbounded preceding and current row )row_num
from test
where video_id=2002;

range 是取范围值的值 
select
    video_id,
    dt,
    sum(if_follow) over (partition by video_id order by if_follow range between unbounded preceding and current row)row_num
from test
where video_id = 2002;

进阶开窗函数

其他开窗函数:

                        ntile(x)功能: 将分组排序之后的数据分成指定的x个部分(x个桶)   
     
 "注意ntile规则:尽量平均分配 ,优先满足最小(编号1)的桶,彼此最多不相差1个"

                        -lag: 用于统计窗口内往上第n行值
                        -lead: 用于统计窗口内往下第n行值

                        -first_value: 取分组内排序后,截止到当前行,第一个值
                        -last_value : 取分组内排序后,截止到当前行,最后一个值

以上就是小浪本次发布的内容,如果对友友您有帮助,还麻烦您给小浪点个关注 和 赞,这是对小浪莫大的支持,蟹蟹友友们,小浪还会持续更新,分享自己在学习整个过程中遇到的问题!  

<think>好的,我现在需要帮助用户理解SQL开窗函数的基本概念和用法。首先,我得回顾一下用户的问题,他明确要求介绍和教程,所以应该从基础开始讲起。用户提供的引用资料里有OracleMySQL的例子,可能需要兼顾不同数据库的语法差异,但用户可能更关注通用部分。 首先,开窗函数的定义是关键。需要说明它和普通聚合函数的区别,比如保持行数不变,同时进行计算。然后,基本语法结构,包括OVER子句里的PARTITION BY、ORDER BY和窗口框架。引用1和引用3都提到了这些部分,可以整合起来。 接下来,常见函数类型需要分类,比如聚合类、排名类、偏移类,这样用户更容易理解。比如SUM、AVG作为聚合,ROW_NUMBER、RANK作为排名,LAG、LEAD作为偏移函数。每个类别举例子,结合用户提供的测试数据,比如T_TEST表中的班级和成绩,这样例子更具体。 然后,使用场景部分,用户可能需要知道什么时候用开窗函数,比如排名、累计计算、前后记录对比,这些实际案例能帮助理解。引用中的例子,比如计算班级排名或累计成绩,可以详细说明。 还要注意不同数据库的语法支持,比如OracleMySQL可能有细微差别,但用户的问题没有特别指定,所以保持通用。同时,提醒用户注意性能问题,比如大数据量下的分区和排序对性能的影响。 最后,生成相关问题时,要考虑用户可能的后续疑问,比如优化方法、与GROUP BY的区别、具体案例分析等。这些能帮助用户深入学习和解决问题。 检查是否需要调整格式,比如数学表达式用$...$,独立公式用$$...$$,但这里可能涉及较少数学内容,主要是代码和示例。确保代码块正确,使用用户提供的测试数据,这样示例更贴切。 总结步骤:定义、语法、函数分类、示例、注意事项、相关问题。保持结构清晰,逐步引导用户从概念到应用。</think>### SQL开窗函数详解 #### 一、基本概念 **开窗函数**(Window Functions)是SQL中用于在数据集的特定子集(窗口)上执行计算的高级函数。与普通聚合函数(如$SUM()$、$AVG()$)不同,开窗函数不会改变原始数据的行数,而是为每一行返回基于窗口计算结果的新列[^1][^3]。 #### 二、核心语法 ```sql <窗口函数> OVER ( [PARTITION BY <列名,...>] -- 分区定义(类似分组) [ORDER BY <列名,...>] -- 窗口内排序 [ROWS BETWEEN <范围>] -- 窗口范围(可选) ) ``` #### 三、常用开窗函数分类 1. **聚合类** - $SUM()$, $AVG()$, $COUNT()$, $MAX()$, $MIN()$ ```sql SELECT 姓名, 成绩, AVG(成绩) OVER (PARTITION BY 班级) AS 班级平均分 FROM T_TEST; ``` 2. **排名类** - $ROW\_NUMBER()$(唯一序号) - $RANK()$(允许并列跳号) - $DENSE\_RANK()$(允许并列不跳号) ```sql SELECT 姓名, 班级, 成绩, RANK() OVER (PARTITION BY 班级 ORDER BY 成绩 DESC) AS 班级排名 FROM T_TEST; ``` 3. **偏移类** - $LAG(列, 偏移量)$(访问前N行) - $LEAD(列, 偏移量)$(访问后N行) ```sql SELECT 姓名, 成绩, LAG(成绩,1) OVER (ORDER BY 成绩) AS 前一名成绩 FROM T_TEST; ``` #### 四、窗口范围控制 通过`ROWS BETWEEN`定义计算范围: - `UNBOUNDED PRECEDING`:从分区首行开始 - `CURRENT ROW`:当前行 - `UNBOUNDED FOLLOWING`:到分区末行结束 **示例**:计算累计成绩 ```sql SELECT 姓名, 成绩, SUM(成绩) OVER (ORDER BY id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS 累计成绩 FROM T_TEST; ``` #### 五、典型应用场景 1. 动态排名(如销售TOP10) 2. 时间序列分析(环比/同比计算) 3. 移动平均值计算 4. 数据对比(与前/后记录比较) #### 六、注意事项 1. OracleMySQL对窗口函数的支持存在版本差异(如MySQL 8.0+支持) 2. 分区字段选择直接影响性能,建议使用索引列 3. 窗口范围定义需注意边界条件
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值