各位老铁们好,相信很多人对开窗函数都不是特别的了解,因此呢,今天就来为大家分享下关于开窗函数以及开窗函数sum over的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看看吧!
在SQL的世界里,开窗函数(Window Function)是一个神秘而又强大的工具。它能够让我们在处理数据时,拥有更广阔的视野,从而挖掘出更多有价值的信息。开窗函数究竟是什么?它有哪些神奇的功能?今天,就让我们一起揭开开窗函数的神秘面纱。
一、开窗函数的定义
开窗函数是一种在SQL查询中计算结果集的特定部分(即“窗口”)的函数。简单来说,就是可以在一个结果集的某个子集上执行计算,而不影响整个结果集。
二、开窗函数的特点
1. 独立于分组(GROUP BY):开窗函数可以在不进行分组的情况下,对整个结果集进行计算。
2. 灵活的窗口大小:窗口大小可以是固定的,也可以是动态的。
3. 丰富的计算方式:开窗函数可以用于计算排名、累计值、移动平均等多种统计指标。
三、开窗函数的应用场景
1. 计算排名:例如,计算每个学生的成绩排名。
2. 计算累计值:例如,计算每个学生的总分。
3. 计算移动平均:例如,计算每个学生的最近五次考试成绩的平均值。
4. 计算分位数:例如,计算每个学生的成绩分位数。
四、开窗函数的基本语法
“`sql
SELECT
column1,
column2,
window_function(column3) OVER (PARTITION BY column1 ORDER BY column2) AS result
FROM
table_name;
“`
解释:
- `window_function`:开窗函数的名称,例如`ROW_NUMBER`、`RANK`、`DENSE_RANK`、`SUM`、`AVG`等。
- `column3`:参与开窗函数计算的列。
- `PARTITION BY column1`:将结果集划分为多个分区,每个分区内的数据将独立计算。
- `ORDER BY column2`:在每个分区内部,按照`column2`的值对数据进行排序。
- `AS result`:为开窗函数的结果列命名。
五、开窗函数的实例
假设我们有一个学生成绩表`student_score`,包含学生ID(`student_id`)、科目(`subject`)和成绩(`score`)三个字段。
1. 计算每个学生的成绩排名
“`sql
SELECT
student_id,
subject,
score,
RANK() OVER (PARTITION BY student_id ORDER BY score DESC) AS rank
FROM
student_score;
“`
2. 计算每个学生的总分
“`sql
SELECT
student_id,
SUM(score) OVER (PARTITION BY student_id) AS total_score
FROM
student_score;
“`
3. 计算每个学生的最近五次考试成绩的平均值
“`sql
SELECT
student_id,
subject,
score,
AVG(score) OVER (PARTITION BY student_id ORDER BY score DESC ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) AS moving_avg
FROM
student_score;
“`
六、总结
开窗函数是SQL中一个非常有用的工具,它可以帮助我们轻松地处理复杂的数据计算。通过掌握开窗函数,我们可以更好地挖掘数据的价值,为业务决策提供有力支持。
以下是一些额外的建议:
- 多练习:通过实际操作,加深对开窗函数的理解。
- 查阅资料:查阅相关书籍、博客和教程,了解开窗函数的高级用法。
- 分享经验:将你的经验和心得分享给他人,共同进步。
希望这篇文章能帮助你更好地理解开窗函数,祝你在SQL的世界里越走越远!
为什么我们要使用开窗函数
什么时候会用到开窗函数呢?下面介绍使用场景:
表test1数据如下:
现在我们有需求:查出它们每个年级(class)的平均分数,预期结果格式如下:
我们可以看到,根据年级class求avg()聚合后的数据会变少一条,但是,我们既要显示聚合前的数据又要显示聚合后的数据,这个时候就要使用开窗函数。
测试:
查询数据:
返回结果:
出现的两个问题:
1.如果我们在partition by class加一个order by id会出现什么问题
返回结果:
可以看到class为1的两条avg值不一致,这是因为order by id是来一条数据处理一条,所以第一条class为1的数据来的只能是99/1=99。
我们可能会这样想,先查询出数据放到一张临时表,然后在开窗,根据class分区,再根据id排序,可是结果并不是根据id全局有序的
返回结果:
因为它是按照分区排序的,所以是分区内有序。
另外,我们和group by分组做个对比
原始数据如下
我们可能会想,为什么同样在这里使用了聚合函数sum(),数据条数变少了,我们为什么没有开窗呢?
这里使用group by进行了分组,根据id和时间进行分组。
那我们想是否上面也可以使用group by而不使用开窗呢?
如下sql是否可以呢?
返回结果:
答案是不可以。因为我们select了多个字段,所以我们要根据多个字段来分组,class相同再根据id分组,id相同再根据score分组。导致我们不能仅仅根据class分组,也就导致最后分组出来的数据除了class、id、score都相同的两条数据能够聚合,否则都是单条数据自己聚合。
所以我们要使用group by就只能选取单个字段
返回结果
懂的讲一下oracle开窗函数都有哪些需要关注哪些点
Oracle开窗函数主要包括以下几种:
ROW_NUMBER()
功能:为结果集的每一行分配一个唯一的连续整数。关注点:通常用于需要对数据进行排序并获取唯一行号的情况。RANK()
功能:类似于ROW_NUMBER(),但为相同值的行分配相同的排名,并跳过随后的排名值。关注点:适用于需要处理具有相同值的数据行,并希望这些行具有相同排名的情况。DENSE_RANK()
功能:类似于RANK(),但为相同值的行分配相同的排名,并且不跳过随后的排名值。关注点:当需要连续排名,不希望排名值出现跳跃时,DENSE_RANK()更为合适。NTILE(n)
功能:将结果集划分为n个桶,并为每桶内的行分配一个桶号。关注点:适用于需要将数据划分为多个均匀部分的情况,如性能分析中的四分位数等。LAG()和 LEAD()
功能:LAG()返回当前行之前的某一行的值,LEAD()返回当前行之后的某一行的值。关注点:这两个函数常用于时间序列分析或需要比较相邻行数据的情况。FIRST_VALUE()和 LAST_VALUE()
功能:FIRST_VALUE()返回窗口内排序后的第一行的值,LAST_VALUE()返回窗口内排序后的最后一行的值。关注点:适用于需要获取窗口内特定位置数据值的情况。在使用开窗函数时,需要关注以下几点:
窗口定义:明确指定窗口的分区和排序规则,这是开窗函数工作的基础。性能影响:开窗函数可能会对查询性能产生影响,特别是在处理大数据集时。因此,需要合理设计查询,并考虑使用索引等优化手段。函数组合:多个开窗函数可以在同一个查询中组合使用,以实现更复杂的分析需求。但需要注意函数之间的相互作用和计算顺序。
开窗函数-lag/lead
Lag函数
LAG函数,专门用于获取当前行之前的数据值。帮助我们轻松查看上一行的信息。其语法格式为:LAG(column_name, offset, default_value) OVER(PARTITION BY partition_column ORDER BY sort_column)。其中,column_name表示需要获取值的列名,offset表示偏移量,即向前查找的行数,default_value是当找不到指定行时返回的默认值。PARTITION BY和ORDER BY则用于数据分组和排序。
Lead函数
Lead函数与Lag函数相似,用于获取当前行之后的数据值。通过Lead函数,我们可以快速查看下一行的数据。其语法格式同样为:LEAD(column_name, offset, default_value) OVER(PARTITION BY partition_column ORDER BY sort_column)。参数含义与Lag函数相同。PARTITION BY和ORDER BY同样用于数据分组和排序。
参数说明
在使用LAG和LEAD函数时,理解参数的含义至关重要。column_name指的是需要获取值的列;offset参数指定向前或向后查找的行数;default_value则用于处理未找到指定行的情况,通常设置为NULL、默认值或其他固定值。PARTITION BY用于将数据集分为多个组,ORDER BY则决定每组内部的排序方式。正确运用这些参数,能够使LAG和LEAD函数在数据分析中发挥重要作用。
关于开窗函数和开窗函数sum over的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。




