SQL窗口函数之排名窗口函数怎么使用

取值窗口函数可以用于返回窗口内指定位置的数据行。常见的取值窗口函数如下:

LAG函数可以返回窗口内当前行之前的第N行数据。LEAD函数可以返回窗口内当前行之后的第N行数据。FIRST_VALUE函数可以返回窗口内名列前茅行数据。LAST_VALUE函数可以返回窗口内最后一行数据。NTH_VALUE函数可以返回窗口内第N行数据。

其中,LAG函数和LEAD函数不支持动态的窗口大小,它们以整个分区作为分析的窗口。

案例分析

案例使用的示例表

下面的查询中会用到一张表,sales_monthly表中存储了商品销量信息,product表示产品名称,ym表示年月,amount表示销售金额(元)。

以下是该表中的部分数据:

SQL窗口函数之排名窗口函数怎么使用

这个表的初始化脚本可以在文章底部获取。

1.环比分析

环比增长指的是本期数据与上期数据相比的增长,例如,产品2019年6月的销售额与2019年5月的销售额相比增加的部分。

以下语句统计了各种产品每个月的环比增长率:

SELECT s.product AS "产品", s.ym AS "年月", s.amount AS "销售额", (     (s.amount - LAG(s.amount,1) OVER (PARTITION BY product ORDER BY s.ym))/    LAG(s.amount,1) OVER (PARTITION BY product ORDER BY s.ym) ) * 100 AS "环比增长率(%)"FROM sales_monthly sORDER BY s.product,s.ym

其中,LAG(amount,1)表示获取上一期的销售额,PARTITION BY选项表示按照产品分区,ORDER BY选项表示按照月份进行排序。

当前月份的销售额amount减去上一期的销售额,再除以上一期的销售额,就是环比增长率。

该查询返回的结果如下:

SQL窗口函数之排名窗口函数怎么使用

2018年1月是名列前茅期,因此其环比增长率为空。

“桔子”2018年2月的环比增长率约为0.2856%((10183-10154)/10154×100),依此类推。

2.同比分析

同比增长指的是本期数据与上一年度或历史同期相比的增长,例如,产品2019年6月的销售额与2018年6月的销售额相比增加的部分。

以下语句统计了各种产品每个月的同比增长率:

SELECT s.product AS "产品", s.ym AS "年月", s.amount AS "销售额", (     (s.amount - LAG(s.amount,12) OVER (PARTITION BY product ORDER BY s.ym))/    LAG(s.amount,12) OVER (PARTITION BY product ORDER BY s.ym) ) * 100 AS "同比增长率(%)"FROM sales_monthly sORDER BY s.product,s.ym

其中,LAG(amount,12)表示当前月份之前第12期的销售额,也就是去年同月份的销售额。

PARTITION BY选项表示按照产品分区,ORDER BY选项表示按照月份进行排序。

当前月份的销售额amount减去去年同期的销售额,再除以去年同期的销售额,就是同比增长率。

该查询返回的结果如下:

SQL窗口函数之排名窗口函数怎么使用

2018年的12期数据都没有对应的同比增长率,“桔子”2019年1月的同比增长率约为9.3067%((11099-10154)/10154×100),依此类推。

提示:LEAD函数与LAG函数的使用方法类似,不过它的返回结果是当前行之后的第N行数据。

3.复合增长率

复合增长率是第N期的数据除以名列前茅期的基准数据,然后开N-1次方再减去1得到的结果。

假如2018年的产品销售额为10000,2019年的产品销售额为12500,2020年的产品销售额为15000。那么这两年的复合增长率的计算方式如下:

SQL窗口函数之排名窗口函数怎么使用

以年度为单位计算的复合增长率被称为年均复合增长率,以月度为单位计算的复合增长率被称为月均复合增长率

以下查询统计了自2018年1月以来不同产品的月均销售额复合增长率:

WITH s (product,ym,amount,first_amount,num) AS (  SELECT m.product, m.ym, m.amount,  FIRST_VALUE(m.amount) OVER (PARTITION BY m.product ORDER BY m.ym),  ROW_NUMBER() OVER (PARTITION BY m.product ORDER BY m.ym)  FROM sales_monthly m) SELECT product AS "产品", ym AS "年月",amount AS "销售额",       (POWER( amount/first_amount, 1.0/NULLIF(num-1,0)) -1)*100 AS "月均复合增长率(%)"FROM sORDER BY product, ym

首先定义了一个通用表表达式,其中FIRST_VALUE(amount)返回了名列前茅期(201801)的销售额,ROW_NUMBER函数返回了每一期的编号。

主查询中的POWER函数用于执行开方运算,NULLIF函数用于处理名列前茅期数据的除零错误,常量1.0用于避免由整数除法所导致的精度丢失问题。

该查询返回的结果如下:

SQL窗口函数之排名窗口函数怎么使用

2018年1月是名列前茅期,因此其产品月均销售额复合增长率为空。

“桔子”2018年2月的月均销售额复合增长率等于它的环比增长率,2018年3月的月均销售额复合增长率等于0.4471%,依此类推。

4.不同产品较高和最低销售额

以下语句统计了不同产品最低销售额、较高销售额以及第三高销售额所在的月份:

  SELECT product AS "产品", ym AS "年月",amount AS "销售额",           FIRST_VALUE(m.ym) OVER (           PARTITION BY m.product ORDER BY m.amount DESC           ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING         ) AS "较高销售额月份",                  LAST_VALUE(m.ym) OVER (           PARTITION BY m.product ORDER BY m.amount DESC           ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING         ) AS "最低销售额月份",                  NTH_VALUE(m.ym,3) OVER (           PARTITION BY m.product ORDER BY m.amount DESC           ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING         ) AS "第三高销售额月份"   FROM sales_monthly m  ORDER BY product, ym;

三个窗口函数的OVER子句相同,PARTITION BY选项表示按照产品进行分区,ORDER BY选项表示按照销售额从高到低排序。

以上三个函数的默认窗口都是从分区的名列前茅行到当前行,因此我们将窗口扩展到了整个分区。

该查询返回的结果如下:

SQL窗口函数之排名窗口函数怎么使用

“桔子”的较高销售额出现在2019年6月,最低销售额出现在2018年1月,第三高销售额出现在2019年4月。

示例表和脚本

-- 创建销量表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);

关于“SQL窗口函数之排名窗口函数怎么使用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注亿速云行业资讯频道,小编每天都会为大家更新不同的知识点。

文章标题:SQL窗口函数之排名窗口函数怎么使用,发布者:亿速云,转载请注明出处:https://worktile.com/kb/p/24230

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
亿速云的头像亿速云认证作者
上一篇 2022年9月10日 下午11:44
下一篇 2022年9月10日 下午11:46

相关推荐

  • 如何用rank函数排名

    用rank函数排名的方法: 1、首先进入空白单元格,然后输入:=RANK( )来进行排名。 2、然后去点击E2单元格,即可获得rank的名列前茅个参数,然后输入逗号。 3、之后就可以去框选所有的数据,并且去获取函数的第二个参数。 4、然后按下F4,即可对rank函数的第二个参数做绝对引用。 5、按下…

    2022年8月30日
    84400
  • SQL Server备份数据库的方法

    一.首先把当前的数据库备份成一个文件 1.按照操作来,选择对应的数据库, 确定备份文件的存储位置 点击确定,生成备份文件。 2.然后可以通过该备份文件还原数据库。 右键数据库点击还原文件和文件组 然后设置目标数据库的名字,如果数据库中已经存在相同名字的,则需要修改或者删除原来同名的数据库,然后在选择…

    2022年9月11日
    57700
  • word页码不连续突然断页怎么设置

    word页码不连续突然断页设置方法: 1、首先进入word文档,并点击上方的插入。 2、然后在菜单内找到点击“页码”选项。 3、在选项中可以看到页码点击。 4、随后在起始页码的后面输入1。 5、最后点击下方的确定保存即可。 读到这里,这篇“word页码不连续突然断页怎么设置”文章已经介绍完毕,想要掌…

    2022年9月20日
    1.7K00
  • word字体放大如何弄

    word字体放大的方法 1、先选中需要放大的字体,然后点击开始菜单中的增大字号。 2、选中字体之后在悬浮框中点击字体大小就可以设置了。 3、选中需要放大的字体之后,点击上方菜单栏中的输入框,直接在里面输入你要的字号。 以上就是“word字体放大如何弄”这篇文章的所有内容,感谢各位的阅读!相信大家阅读…

    2022年9月10日
    54000
  • laravel是不是aop

    laravel不是aop;aop是“Aspect Oriented Programming”的缩写,意为面向切面编程,是通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术,而laravel不是面向切片编程,laravel中间件提供了一种方便的机制来检查和过滤进入应用程序的HTTP请求是…

    2022年9月1日
    52000
  • 电脑0xc06d007e如何解决

    0xc06d007e修复方法: 方法一: 1、首先,如果我们是在开启一些图像处理软件或是播放器软件时才会出现问题。 2、那么就可能是因为电脑缺少了Windows Media player软件。 3、下载安装完成后,大家可以尝试再去打开软件,如果打不开的话再尝试下面的方法。 方法二: 1、如果上面的方…

    2022年9月18日
    1.8K00
  • windows edge浏览器缓存位置如何修改

    edge浏览器缓存位置更改方法: 1、进入edge浏览器的路径位置,删除“Cache”缓存文件夹。 2、右击开始,选择“命令提示符(管理员)”。 3、输入命令 mklink /D “C:Users用户名AppDataLocalPackagesMicrosoft.MicrosoftEdge…

    2022年9月8日
    1.5K00
  • pr如何修改视频分辨率

    pr修改视频分辨率的方法: 1、首先进入pr,然后依次点击“新建项目”点击确定。 2、然后可以看到pr自带的多种选择可以自由选择分辨率。 3、还可以去通过设置,来自定义自己需要的剪辑尺寸。 4、可以根据需求来定义,哪怕是手机尺寸也可以。 5、设置好了可以点击“存储预设”来进行保存。 6、等到保存完成…

    2022年8月29日
    2.4K00
  • MySQL日志管理怎么配置

    MySQL的日志默认保存在数据库文件的存储目录(一般为/usr/local/mysql/data/)。也可以修改配置文件,自定义日志文件的保存位置。 我这里在编译安装时,数据库文件存储目录设置的是/home/mysql。 一、四种日志介绍 1.1 错误日志 错误日志,用来记录当MySQL启动、停止或…

    2022年9月21日
    1.2K00
  • SpringBoot怎么进行整合Druid数据源

    1.自定义方式 使用自定义方式整合Druid 1.添加依赖 在pom.xml添加相关依赖 <!–数据库相关–> <dependency> <groupId>org.springframework.boot</groupId> <artifac…

    2022年9月15日
    56400
注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部