SQL 聚合窗口函数包括什么,具体如何应用
Admin 2022-08-08 群英技术资讯 330 次浏览
案例使用的示例表
下面的查询中会用到两个表,其中sales_monthly表中存储了不同产品(苹果、香蕉、橘子)每个月的销售额情况。以下是该表中的部分数据:
transfer_log表中记录了一些银行账户的交易日志。以下是该表中的部分数据:
该表中的字段分别表示交易日志编号、交易时间、交易发起账户、交易接收账户、交易类型以及交易金额。这两个表的初始化脚本可以在文章底部获取。
AVG函数在作为窗口函数使用时,可以用于计算随着当前行移动的窗口内数据行的平均值。
例如,以下语句用于查找不同产品每个月以及截至当前月最近3个月的平均销售额
SELECT m.product,m.ym,m.amount, AVG(m.amount) OVER( PARTITION BY m.product ORDER BY m.ym ROWS BETWEEN 2 PRECEDING AND CURRENT ROW ) FROM sales_monthly m ORDER BY m.product,m.ym
AVG函数OVER子句中的PARTITION BY选项表示按照产品进行分区。
ORDER BY选项表示按照月份进行排序;ROWS BETWEEN 2 PRECEDING AND CURRENT ROW表示窗口从当前行的前2行开始,直到当前行结束。该查询返回的结果如下:
对于“橘子”:
第一个月的分析窗口只有1行数据,因此平均销售额为“10154”。
第二个月的分析窗口为第1行和第2行数据,因此平均销售额为“10168.5”((10154+10183)/2)。
第三个月的分析窗口为第1行到第3行数据,因此平均销售额为“10194”((10154+10183+10245)/3)。
依此类推,直到计算完“橘子”所有月份的平均销售额,然后开始计算其他产品的平均销售额。
SUM函数作为窗口函数时,可以用于统计指定窗口内的累计值。
例如,以下语句用于查找不同产品截至当前月份的累计销售额:
SELECT m.product,m.ym,m.amount, SUM(m.amount) OVER( PARTITION BY m.product ORDER BY m.ym ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM sales_monthly m ORDER BY m.product,m.ym
SUM函数OVER子句中的PARTITION BY选项表示按照产品进行分区。
ORDER BY选项表示按照月份进行排序。
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW表示窗口从当前分区第1行开始,直到当前行结束。
该查询返回的结果如下:
对于“橘子”:
第一个月的分析窗口只有1行数据,因此累计销售额为“10154”。
第二个月的分析窗口为第1行和第2行数据,因此累计销售额为“20337”(10154+10183)。
第三个月的分析窗口为第1行到第3行数据,因此累计销售额为“30582”(10154+10183+10245)。
依此类推,直到计算完“橘子”所有月份的累计销售额,然后开始计算其他产品的累计销售额。
提示:对于聚合窗口函数,如果我们没有指定ORDER BY选项,默认的窗口大小就是整个分区。
如果我们指定了ORDER BY选项,默认的窗口大小就是分区的第一行到当前行。
因此,以上示例语句中的ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW选项可以省略。省略后的语句:
执行结果与上面相同。
如果去掉ORDER BY选项,查询的窗口大小就是整个分区,如下图所示:
这时,合计值就变成了分区内所有记录的合计。
除使用ROWS关键字以数据行为单位指定窗口的偏移量外,我们也可以使用RANGE关键字以数值为单位指定窗口的偏移量。
例如,以下语句用于查找短期之内(5天)累计转账超过100万元的账户:
SELECT log_ts,from_user,total_amount FROM ( SELECT to_char(t.log_ts,'yyyy-mm-dd hh24:mi:ss') log_ts,t.from_user,t.amount, SUM(t.amount) OVER( PARTITION BY t.from_user ORDER BY t.log_ts RANGE INTERVAL '5' DAY PRECEDING ) AS total_amount FROM transfer_log t WHERE t.type = '转账' ) WHERE total_amount >= 1000000;
其中,SUM函数OVER子句中的RANGE选项指定了一个5天之内的时间窗口。该查询返回的结果如下:
截至2021年1月10日7时46分02秒,账户“62221234567890”在最近5天之内累计转账105万元。
-- 创建销量表sales_monthly -- product表示产品名称,ym表示年月,amount表示销售金额(元) CREATE TABLE sales_monthly(product VARCHAR(20), ym VARCHAR(10), amount NUMERIC(10, 2)); -- 生成测试数据 INSERT INTO sales_monthly (product,ym,amount) VALUES ('苹果','201801',10159.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('苹果','201802',10211.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('苹果','201803',10247.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('苹果','201804',10376.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('苹果','201805',10400.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('苹果','201806',10565.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('苹果','201807',10613.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('苹果','201808',10696.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('苹果','201809',10751.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('苹果','201810',10842.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('苹果','201811',10900.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('苹果','201812',10972.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('苹果','201901',11155.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('苹果','201902',11202.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('苹果','201903',11260.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('苹果','201904',11341.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('苹果','201905',11459.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('苹果','201906',11560.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('香蕉','201801',10138.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('香蕉','201802',10194.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('香蕉','201803',10328.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('香蕉','201804',10322.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('香蕉','201805',10481.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('香蕉','201806',10502.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('香蕉','201807',10589.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('香蕉','201808',10681.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('香蕉','201809',10798.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('香蕉','201810',10829.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('香蕉','201811',10913.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('香蕉','201812',11056.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('香蕉','201901',11161.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('香蕉','201902',11173.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('香蕉','201903',11288.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('香蕉','201904',11408.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('香蕉','201905',11469.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('香蕉','201906',11528.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('桔子','201801',10154.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('桔子','201802',10183.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('桔子','201803',10245.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('桔子','201804',10325.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('桔子','201805',10465.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('桔子','201806',10505.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('桔子','201807',10578.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('桔子','201808',10680.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('桔子','201809',10788.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('桔子','201810',10838.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('桔子','201811',10942.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('桔子','201812',10988.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('桔子','201901',11099.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('桔子','201902',11181.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('桔子','201903',11302.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('桔子','201904',11327.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('桔子','201905',11423.00); INSERT INTO sales_monthly (product,ym,amount) VALUES ('桔子','201906',11524.00); -- 创建银行交易日志表transfer_log -- Oracle、MySQL、PostgreSQL以及SQLite CREATE TABLE transfer_log ( log_id INTEGER NOT NULL PRIMARY KEY, -- 交易日志编号 log_ts TIMESTAMP NOT NULL, -- 交易时间 from_user VARCHAR(50) NOT NULL, -- 交易发起账号 to_user VARCHAR(50), -- 交易接收账号 type VARCHAR(10) NOT NULL, -- 交易类型 amount NUMERIC(10) NOT NULL -- 交易金额(元) ); -- 生成测试数据 -- Oracle 需要执行以下ALTER语句 ALTER SESSION SET nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS'; INSERT INTO transfer_log (log_id,log_ts,from_user,to_user,type,amount) VALUES (1,'2021-01-02 10:31:40','62221234567890',NULL,'存款',50000); INSERT INTO transfer_log (log_id,log_ts,from_user,to_user,type,amount) VALUES (2,'2021-01-02 10:32:15','62221234567890',NULL,'存款',100000); INSERT INTO transfer_log (log_id,log_ts,from_user,to_user,type,amount) VALUES (3,'2021-01-03 08:14:29','62221234567890','62226666666666','转账',200000); INSERT INTO transfer_log (log_id,log_ts,from_user,to_user,type,amount) VALUES (4,'2021-01-05 13:55:38','62221234567890','62226666666666','转账',150000); INSERT INTO transfer_log (log_id,log_ts,from_user,to_user,type,amount) VALUES (5,'2021-01-07 20:00:31','62221234567890','62227777777777','转账',300000); INSERT INTO transfer_log (log_id,log_ts,from_user,to_user,type,amount) VALUES (6,'2021-01-09 17:28:07','62221234567890','62227777777777','转账',500000); INSERT INTO transfer_log (log_id,log_ts,from_user,to_user,type,amount) VALUES (7,'2021-01-10 07:46:02','62221234567890','62227777777777','转账',100000); INSERT INTO transfer_log (log_id,log_ts,from_user,to_user,type,amount) VALUES (8,'2021-01-11 09:36:53','62221234567890',NULL,'存款',40000); INSERT INTO transfer_log (log_id,log_ts,from_user,to_user,type,amount) VALUES (9,'2021-01-12 07:10:01','62221234567890','62228888888881','转账',10000); INSERT INTO transfer_log (log_id,log_ts,from_user,to_user,type,amount) VALUES (10,'2021-01-12 07:11:12','62221234567890','62228888888882','转账',8000); INSERT INTO transfer_log (log_id,log_ts,from_user,to_user,type,amount) VALUES (11,'2021-01-12 07:12:36','62221234567890','62228888888883','转账',5000); INSERT INTO transfer_log (log_id,log_ts,from_user,to_user,type,amount) VALUES (12,'2021-01-12 07:13:55','62221234567890','62228888888884','转账',6000); INSERT INTO transfer_log (log_id,log_ts,from_user,to_user,type,amount) VALUES (13,'2021-01-12 07:14:24','62221234567890','62228888888885','转账',7000); INSERT INTO transfer_log (log_id,log_ts,from_user,to_user,type,amount) VALUES (14,'2021-01-21 12:11:16','62221234567890','62228888888885','转账',70000);
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
这篇文章介绍了SQL Server删除表中重复数据的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
这篇文章主要介绍了SQLServer清理日志文件方法案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
这篇文章主要介绍了Sqlserver 自定义函数 Function使用介绍,在sqlserver2008中有3中自定义函数:标量函数/内联表值函数/多语句表值函数,需要的朋友可以参考下
SQL视图无非就是存储在数据库中并具有名字的 SQL 语句,或者说是以预定义的 SQL 查询的形式存在的数据表的成分。视图可以包含表中的所有列,或者仅包含选定的列。视图可以创建自一个或者多个表,这取决于创建该视图的 SQL 语句的写法。
文章目录遇到的问题使用SQLServerProfiler监控数据库SQL1:查找最新的30条告警事件SQL2:获取当前的总报警记录数...
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008