- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
上一篇文章 《如何用窗口函数实现排名计算》 中小编为大家介绍了窗口函数在排名计算场景中的应用,但实际上窗口函数除了可以进行单行计算,还可以在每行上打开一个指定大小的计算窗口,这个计算窗口可以由SQL中的语句具体指定,大到整个分区作用域,小到当前行指定的某个偏移行(比如 当前行的上一行、下一行,整个计算窗口被称作 frame)。今天小编就为大家介绍窗口函数在累计分析场景中的应用.
需要注意的是,如果您的数据库版本低于以下版本,将无法使用文章中使用到的窗口函数.
1.Mysql (>=8.0) 。
2. PostgreSQL(>=11) 3. SQL Server(>=2012) 4. Oracle(>=8i) 5. SQLite(>=3.28.0) 。
和上一篇文章一样,为了让大家更好的理解,我将以工厂的耗材损耗数据作为查询条件背景:假设现在有某个工厂刚刚完成了一次耗材的加工,在加工的过程中记录了耗材分类,每日的记录时间、每日的耗材耗损数和当月的月初耗材供给量,如下表所示:
现在这家公司的老板想看一下:
1. 各个耗材的每日累计损耗量.
2. 各个耗材的当月每日余量.
3. 各个耗材的每月累计消耗占比.
执行如下的SQL语句.
select cate,record_date,init_value,SUM(cost) over(partition by cate,MONTH(record_date) order by record_date ) as cm_cost
from material_data md;
可以看到,通过上述 SQL 查询就已经得到了每个分类每月的每日累计耗损量。这里为大家解释下SQL中的重点部分:
SUM(cost) over(partition by cate,MONTH(record_date) order by record_date );
在上一篇文章中我们介绍过,partition by 指定了计算分区, order by 决定了计算的行顺序, 那累计效果又是谁来完成的呢, 这里小编把刚刚的 SQL 稍微改造一下就会更清晰.
select cate,record_date,init_value,SUM(cost) over(partition by cate,MONTH(record_date) order by record_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) as cm_cost
from material_data md;
改造后的SQL和最开始的查询SQL达成的效果是一致的, 我们可以看到改造SQL在 order by 后加了一段代码:
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
小编为大家拆解一下这个代码,第一个 ROWS 表示接下来的 Frame 窗口指定为行模式, BETWEEN 关键字表示接下来的语句效果是指定 窗口范围, UNBOUNDED 和PRECEDING 是两个关键字的组合,前者表示 该计算窗口在 ↑ 方向的边界为最顶部,对应到 partion by 分区中 6 月份的计算域,UNBOUNDED PRECEDING 表示6月份每一行的窗口上界为 order by record_date 顺序下的最小值,即 2023/06/01号的记录, 同样的 接下来的 AND CURRENT ROW 则指定了计算frame 窗口的 ↓ 边界为当前行。 最后我们重新梳理下这个计算窗口, 在每月每个分类的计算分区下,每一行的计算窗口为 从本月的最小日期 到当前行的所有记录,,联系到最开始 SUM(cost) 聚合就能够理解 为什么这条 SQL 能计算出对应的累计值了.
这里可以扩展说明一下,确定计算窗口大小的关键字 除了UNBOUNDED PRECEDING和CURRENT ROW 之外还有 UNBOUNDED FOLLOWING, 如果 UNBOUNDED PRECEDING 表示上边界的顶部, 那 UNBOUNDED FOLLOWING 就表示下边界的底部。所以如果指定计算窗口为 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING, 则表示在整个分区计算域中进行聚合运算。另外, UNBOUNDED 其实是非必须的, 这里可以替换为任意数字表示 针对当前行的偏移行数。比如 1 PRECEDING 表示 当前行的上一行, 1 FOLLOWING 表示当前行的下一行, 我们通过指定计算窗口为 ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING 就能计算 每一行从上一行到下一行之间这三行的累计值。至于说 CURRENT ROW 则指定为当前行,这也是为什么能做累计求和的关键。 类似的,MAX()、AVG() 等聚合函数也适用于以上的规则, 我们可以在每一行的指定窗口内来计算最大值,平均值等聚合值.
查询Sql:
select
cate,
record_date,
init_value,
init_value - SUM(cost) over(partition by cate,MONTH(record_date) order by record_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) as material_num
from material_data md;
也可以简写为 。
select
cate,
record_date,
init_value,
init_value - SUM(cost) over(partition by cate,MONTH(record_date) order by record_date ) as material_num
from material_data md;
select
md.cate,
record_date,
init_value,
cost/ sum(cost) over(partition by cate,MONTH(record_date) ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as cm_cost
from material_data md
同理,可以简写为:
select
md.cate,
record_date,
init_value,
cost/ sum(cost) over(partition by cate,MONTH(record_date)) as cm_cost
from material_data md
接着就可以根据每天的消耗量占比,来挖掘实际业务场景, 对异常消耗量数据进行对应跟踪.
累计运算也是窗口函数在业务场景中使用得最频繁得一个场景,尤其是销售业务累计排名,业务器材每日消耗程度, 每日余量警报等场景都会用到, 希望能对各位有所帮助。而关于 frame计算窗口得灵活调整还有更多丰富特性,后续(第三篇)还会为大家介绍偏移计算场景.
扩展链接:
如何快速实现多人协同编辑?
Excel中自定义手写签名 。
高级SQL分析函数-窗口函数(1)- 排名计算 。
最后此篇关于窗口函数大揭秘!轻松计算数据累计占比,玩转数据分析的绝佳利器的文章就讲到这里了,如果你想了解更多关于窗口函数大揭秘!轻松计算数据累计占比,玩转数据分析的绝佳利器的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我对以下需要使用 SQL 查询而不是 plsql 来解决的问题感到困惑。这个想法是建立一个累积列来计算之前的所有月份。输入表看起来像 Month 1 2 3 .. 24 我需要建立下表:
我正在寻找一个整洁的解决方案,最好使用 tidyverse 这个问题符合this answer ,但它确实有一个额外的扭曲。我的数据有一个整体分组变量“grp”。在每个这样的组中,我想根据“试验”定义
我正在尝试在 Spotfire 中创建一个运行余额列,该列应该如下图所示。本质上,我想逐行计算“金额”列的累积总计,并且我希望它随着日期的变化从 0 开始。 我尝试过几个 OVER 函数:Sum([A
我是一名优秀的程序员,十分优秀!