POSTGRESQL中如何利用SQL语句快速的进行同环比?

1. 引言

在数据驱动的时代,了解销售、收入或任何业务指标的同比和环比情况对企业决策至关重要。本文将深入介绍如何利用 PostgreSQL 和 SQL 语句快速、准确地进行这两种重要分析。

2. 数据准备

为了演示,假设我们有一张 sales 表,存储了销售数据,包括 date(日期)、product_id(产品ID)、revenue(收入)等字段。首先,确保数据准备工作:

CREATE TABLE sales (date DATE,product_id INT,revenue DECIMAL(10, 2)
);INSERT INTO sales VALUES('2020-01-01', 1, 400),('2020-01-02', 1, 300),('2020-01-01', 2, 3000),('2020-01-02', 2, 3200),('2022-01-01', 1, 500),('2022-01-02', 1, 600),('2022-01-01', 2, 1200),('2022-01-02', 2, 1900),('2023-01-01', 1, 1000),('2023-01-02', 1, 1200),('2023-01-01', 2, 800),('2023-01-02', 2, 900);

插入上述数据后,进行数据查询:

SELECT* 
FROMsales 
ORDER BYproduct_id,DATE;

查询结果如下:
1

3. 时间序列数据处理

处理时间序列数据是同比和环比分析的关键。确保日期字段以正确的数据类型存储:

ALTER TABLE sales
ALTER COLUMN date SET DATA TYPE DATE;

4. 同比分析

同比分析是比较同一时间段内不同年份数据的变化情况。

4.1 对两年的数据进行对比

比如我们现在想看各年的总收入和平均收入。

SELECTEXTRACT(YEAR FROM date) AS year,sum(revenue) as sum_revenue,count(revenue) as count_revenue,AVG(revenue) AS avg_revenue
FROM sales
GROUP BY year
ORDER BY year;

运行后,结果如下:
2

4.2 计算两年的差额和同比

不考虑日期不连续的情况,即销售数据在原始序列中是每年连续的,如数据源中的2022年和2023年收入数据。代码如下:

--计算同比
WITH yearly_revenue AS (SELECTEXTRACT(YEAR FROM date) AS year,sum(revenue) as year_total_revenue,AVG(revenue) AS year_avg_revenueFROM salesWHERE EXTRACT(YEAR FROM date) in (2022,2023)GROUP BY year
)
select 
year,
year_total_revenue,
year_avg_revenue,
lag(year_total_revenue) over (partition by null order by year ) as pre_year_total_revenue, --计算去年的收入
COALESCE(year_total_revenue - LAG(year_total_revenue) OVER (ORDER BY year) , 0) AS yoy_growth_value, --计算各年之间的收入差额
COALESCE((year_total_revenue - LAG(year_total_revenue) OVER (ORDER BY year)) / NULLIF(LAG(year_total_revenue) OVER (ORDER BY year), 0) * 100, 0) AS yoy_growth_rate, --计算两年之间的增长比例
lag(year_avg_revenue) over (partition by null order by year ) as pre_year_avg_revenue, --计算去年的平均收入
COALESCE((year_avg_revenue - LAG(year_avg_revenue) OVER (ORDER BY year)) / NULLIF(LAG(year_avg_revenue) OVER (ORDER BY year), 0) * 100, 0) AS yoy_avg_growth_rate --计算平均收入增长比例
from yearly_revenue;

运行上述代码后,可以直接进行计算收入的同比数据,上述代码考虑了去年收入为0和为null的情况,运行后结果如下:

3

考虑日期不连续的情况,即销售数据在原始序列中是每年连续的,如数据源中的2020年和2022年收入数据。代码如下:

WITH yearly_revenue AS (SELECTEXTRACT(YEAR FROM date) AS year,SUM(revenue) AS year_total_revenue,AVG(revenue) AS year_avg_revenueFROM salesGROUP BY year
)
SELECTcurrent_year.year,current_year.year_total_revenue,previous_year.year_total_revenue AS last_year_total_revenue,previous_year.year_avg_revenue AS last_year_avg_revenue,COALESCE(current_year.year_total_revenue - previous_year.year_total_revenue,0)   yoy_growth_value,COALESCE(current_year.year_total_revenue / nullif(previous_year.year_total_revenue,0)-1,0) * 100  yoy_growth_rate
--   ,CASE
--     WHEN previous_year.year_total_revenue IS NOT NULL THEN
--       (current_year.year_total_revenue - previous_year.year_total_revenue) / previous_year.year_total_revenue * 100
--     ELSE
--       NULL
--   END AS year_on_year_growth
FROMyearly_revenue current_year
LEFT JOINyearly_revenue previous_year ON current_year.year = previous_year.year + 1
-- WHERE 
-- 	previous_year.year_total_revenue is not null
ORDER BYcurrent_year.year;

运行代码后,结果如下:
4

4.3 细分后的同比计算

我们只需要将上述的代码进行简单的修改后,就可以统计细分到任意维度的同比计算。代码如下:

	WITH yearly_revenue AS (SELECTEXTRACT(YEAR FROM date) AS year,product_id,SUM(revenue) AS year_total_revenue,AVG(revenue) AS year_avg_revenueFROM salesGROUP BY year,product_id
)
SELECTcurrent_year.year,current_year.product_id,current_year.year_total_revenue,previous_year.year_total_revenue AS last_year_total_revenue,previous_year.year_avg_revenue AS last_year_avg_revenue,COALESCE(current_year.year_total_revenue - previous_year.year_total_revenue,0)   yoy_growth_value,COALESCE(current_year.year_total_revenue / NULLIF(previous_year.year_total_revenue, 0) - 1, 0) * 100  yoy_growth_rate
--   ,CASE
--     WHEN previous_year.year_total_revenue IS NOT NULL THEN
--       (current_year.year_total_revenue - previous_year.year_total_revenue) / previous_year.year_total_revenue * 100
--     ELSE
--       NULL
--   END AS year_on_year_growth
FROMyearly_revenue current_year
LEFT JOINyearly_revenue previous_year ON current_year.year = previous_year.year + 1 and current_year.product_id = previous_year.product_id
-- WHERE 
-- 	previous_year.year_total_revenue is not null
ORDER BYcurrent_year.year,current_year.product_id;

运行上述代码后,结果如下:
5

5. 环比分析

环比分析是比较相邻时间段的数据变化情况。

5.1 简单的日期环比计算

不考虑数据缺失的情况下,如果要对2023年product_id为1的产品进行环比计算,可以使用以下代码进行简单的环比计算:

SELECTdate,revenue,LAG(revenue) OVER (ORDER BY date) AS prev_revenue,(revenue - LAG(revenue) OVER (ORDER BY date)) / LAG(revenue) OVER (ORDER BY date) * 100 AS growth_rate
FROM sales
WHEREextract(year from date) in (2023) and product_id in (1);

筛选后的数据:
5.1.1

进行计算后的数据:
5.1.2

5.2 先聚合再进行环比计算

在不考虑日期缺失情况下,如果我们要计算2023年的收入环比,那么我们就需要先按照日期进行聚合,然后再进行环比计算。这里有两种方法,代码如下:

-- 计算写法1
WITH daily_revenue AS (SELECTdate,sum(revenue) as day_total_revenueFROM salesGROUP BY date
)
select 
*,
LAG(day_total_revenue) OVER (ORDER BY day_total_revenue) AS prev_revenue,
COALESCE((day_total_revenue - LAG(day_total_revenue) OVER (ORDER BY date)),0) day_growth_value,
COALESCE((day_total_revenue - LAG(day_total_revenue) OVER (ORDER BY date)) / LAG(day_total_revenue) OVER (ORDER BY date) * 100,0) AS day_growth_rate
from daily_revenue
WHERE EXTRACT(YEAR FROM date) in (2023);
#计算写法2
SELECTdate,sum(revenue),LAG(sum(revenue)) OVER (ORDER BY date) AS prev_revenue,COALESCE((sum(revenue) - LAG(sum(revenue)) OVER (ORDER BY date)),0) day_growth_value,COALESCE((sum(revenue) - LAG(sum(revenue)) OVER (ORDER BY date)) / LAG(sum(revenue)) OVER (ORDER BY date) * 100,0) AS growth_rate
FROM sales
WHEREextract(year from date) in (2023)group by date;

无论那个代码都可以,运行后结果如下:
5.2.1

5.3 考虑日期不连续的环比计算

然而在现实统计中,我们的日期往往是不连续的,因此可以考虑下面的思路:

  • 1、先按照所需维度进行如何;
  • 2、进行日期拼接和计算

代码如下:

-- 1.先聚合到指定维度		
WITH daily_revenue AS (SELECT DATE, SUM ( revenue )	AS day_total_revenue FROM sales GROUP BY DATE 
) 
-- 2.再进行拼接
SELECTcurrent_day.DATE,current_day.day_total_revenue,prev_day.day_total_revenue prev_day_total_revenue,COALESCE ( current_day.day_total_revenue - prev_day.day_total_revenue, 0 ) day_growth_value,COALESCE ( current_day.day_total_revenue / NULLIF ( prev_day.day_total_revenue, 0 ) - 1, 0 ) * 100 day_growth_rate  --处理异常情况
FROMdaily_revenue current_dayLEFT JOIN daily_revenue prev_day ON DATE_TRUNC( 'day', current_day.DATE ) = DATE_TRUNC( 'day', prev_day.DATE ) + INTERVAL '1 day' 
-- WHERE 
-- prev_day.day_total_revenue is not nullORDER BYDATE;

运行后,效果如下:
5.3.1

6. 性能优化技巧

数据库性能是关键,特别是在处理大量数据时。

-- 为 date 列创建索引
CREATE INDEX idx_date ON sales (date);
-- 向上方一样,采用视图
WITH daily_revenue AS (SELECT DATE, SUM ( revenue )	AS day_total_revenue FROM sales GROUP BY DATE 
) SELECT *
FROMdaily_revenue;

7. 注意事项与常见问题

数据规范性和异常值处理是关键。确保日期格式正确,避免数据异常对分析造成的影响。

8. 结语

本文介绍了在 PostgreSQL 中利用 SQL 进行同比和环比分析的方法。从数据准备到复杂场景下的 SQL 查询,每一步都经过详细解释和示例演示。这些技能不仅能提升数据分析效率,还能为业务决策提供重要支持。利用这些方法,你可以更加准确、快速地分析业务数据,为企业带来更大价值。

希望这篇文章能帮助你更好地利用 SQL 在 PostgreSQL 中进行同比和环比分析!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/191029.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【PyTorch】线性回归

文章目录 1. 代码实现1.1 一元线性回归模型的训练 2. 代码解读2.1. tensorboardX2.1.1. tensorboardX的安装2.1.2. tensorboardX的使用 1. 代码实现 波士顿房价数据集下载 1.1 一元线性回归模型的训练 import numpy as np import torch import torch.nn as nn from torch.ut…

深度学习:什么是知识蒸馏(Knowledge Distillation)

1 概况 1.1 定义 知识蒸馏(Knowledge Distillation)是一种深度学习技术,旨在将一个复杂模型(通常称为“教师模型”)的知识转移到一个更简单、更小的模型(称为“学生模型”)中。这一技术由Hint…

二叉树遍历及应用

文章目录 前言构建二叉树前序遍历中序遍历后序遍历二叉树的结点个数二叉树的叶节点个数二叉树的高度二叉树第K层结点个数 前言 二叉树的遍历及应用主要是运用了递归、分治的思想。在这一篇文章,小编将介绍二叉树的前序遍历、中序遍历、后序遍历,求二叉树…

Fiddler抓包工具之fiddler设置手机端抓包

fiddler设置手机端抓包 安卓手机抓包 第一步:配置电脑和安卓的相关设置 1、手机和fiddler位于同一个局域网内;首先从fiddler处获取到ip地址和端口号: ,点击online,最后一行就是ip地址 2、路径:Tools》O…

【ASP.NET CORE】数据迁移 codefirst

已经写好实体类,使用add-migration生成数据迁移语句,注意如果项目中有多个dbcontext需要使用 -context 名称,指定下需要使用的dbcontext add-Migration Address -context mvcsqlcontext运行后会生成两个文件 2. 使用Update-Database语句更…

Web自动化测试详解

做测试的同学们都了解,做Web自动化,我们主要用Selenium或者是QTP。 有的人可能就会说,我没这个Java基础,没有Selenium基础,能行吗?测试虽然属于计算机行业,但其实并不需要太深入的编程知识&…

C++学习之路(十六)C++ 用Qt5实现一个工具箱(为屏幕颜色提取功能增加一个点击复制的功能)- 示例代码拆分讲解

上篇文章,我们用 Qt5 实现了在小工具箱中添加了《颜色代码转换和屏幕颜色提取功能》功能。今天我们把屏幕颜色提取的功能再扩展一下,让它可以点击复制吧。下面我们就来看看如何来规划开发这样的小功能并且添加到我们的工具箱中吧。 老规矩,先…

数字图像处理(实践篇)十三 数据增强之给图像添加噪声!

目录 一 涉及的函数 二 实践 一 涉及的函数 skimage.util.random_noise( ) skimage.util.random_noise(image, modegaussian, seedNone, clipTrue, **kwargs) 函数的功能:为浮点型图片添加各种随机噪声。 输入: ①image:输入图像&…

【C/C++笔试练习】公有派生、构造函数内不执行多态、抽象类和纯虚函数、多态中的缺省值、虚函数的描述、纯虚函数的声明、查找输入整数二进制中1的个数、手套

文章目录 C/C笔试练习选择部分(1)公有派生(2)构造函数内不执行多态(3)抽象类和纯虚函数(4)多态中的缺省值(5)程序分析(6)重载和隐藏&a…

【开箱即用】前后端同时开源!周末和AI用Go语言共同研发了一款笔记留言小程序!

大家好,我是豆小匠。 真的是当你在怀疑AI会不会取代人类的时候,别人已经用AI工具加速几倍的生产速度了… 周末体验了和AI共同开发的感受,小项目真的可以一人全干了… 本次实验使用的AI工具有两个:1. GitHub Copilot(…

前端文本省略号后面添加复制文字

前端文本省略号后面添加复制文字 1、效果图 2、代码展示 <div class"link-content-wrap" click"copyLinkText"><div class"link-content">{{ shareResult.url || }} </div><span class"show-ellipsis" click&…

(五)Tiki-taka算法(TTA)求解无人机三维路径规划研究(MATLAB)

一、无人机模型简介&#xff1a; 单个无人机三维路径规划问题及其建模_IT猿手的博客-CSDN博客 参考文献&#xff1a; [1]胡观凯,钟建华,李永正,黎万洪.基于IPSO-GA算法的无人机三维路径规划[J].现代电子技术,2023,46(07):115-120 二、Tiki-taka算法&#xff08;TTA&#xf…

深入浅出强化学习

目录 一、强化学习的概念 二、强化学习的特点 三、强化学习的训练过程 一、强化学习的概念 强化学习是一种机器学习方法&#xff0c;旨在教会算法如何通过与环境的交互来进行学习和决策。与传统的监督学习和无监督学习不同&#xff0c;强化学习侧重于学习与奖励和惩罚&#…

详解原生Spring框架下的方法切入点表达式

&#x1f609;&#x1f609; 学习交流群&#xff1a; ✅✅1&#xff1a;这是孙哥suns给大家的福利&#xff01; ✨✨2&#xff1a;我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料 &#x1f96d;&#x1f96d;3&#xff1a;QQ群&#xff1a;583783…

春秋云镜 CVE-2022-30887

春秋云镜 CVE-2022-30887 多语言药房管理系统 (MPMS) 靶场介绍 多语言药房管理系统 (MPMS) 是用 PHP 和 MySQL 开发的, 该软件的主要目的是在药房和客户之间提供一套接口&#xff0c;客户是该软件的主要用户。该软件有助于为药房业务创建一个综合数据库&#xff0c;并根据到期…

Linux中top命令输出日志分析?

以下是对输出的各部分的解释&#xff1a; 09:54:34&#xff1a;系统当前时间。up 161 days, 2:08&#xff1a;系统已经运行了161天2小时8分钟。5 users&#xff1a;有5个用户登录系统。load average: 0.13, 0.08, 0.05&#xff1a;系统的1分钟、5分钟、15分钟的平均负载。负载…

钢铁ERP系统有哪些?钢铁ERP软件哪家好用

不同的钢铁材料有差异化的产成品&#xff0c;而这些成品又有多元化的营销策略和制造工艺&#xff0c;每道生产工艺存在差异化的管理方式与策略&#xff0c;而不同的销售策略对应多样化的价格机制等&#xff0c;繁多的业务数据采集和分析工作量较大。 近些年制造工艺的变革也促…

精通Git(第2版)读书笔记

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言第 1章 入门 11.1 关于版本控制 11.1.1 本地版本控制系统 1 第 2章 Git基础 132.1 获取Git仓库 132.1.1 在现有中初始化Git仓库 132.1.2 克隆现有仓库 14 2.2 在…

Python函数的高级用法

Python 的函数是“一等公民”&#xff0c;因此函数本身也是一个对象&#xff0c;函数既可用于赋值&#xff0c;也可用作其他函数的参数&#xff0c;还可作为其他函数的返回值。 使用函数变量 Python 的函数也是一种值&#xff1a;所有函数都是 function 对象&#xff0c;这意…

人工智能学习5(特征抽取)

编译环境&#xff1a;PyCharm 文章目录 编译环境&#xff1a;PyCharm 特征抽取无监督特征抽取(之PCA)代码实现鸢尾花数据集无监督特征抽取 有监督特征抽取(之LDA)代码实现,生成自己的数据集并进行有监督特征抽取(LDA)生成自己的数据集PCA降维和LDA降维对比 代码实现LDA降维对鸢…