专业编程基础技术教程

网站首页 > 基础教程 正文

Hive内置函数add_months()使用详解:计算环比与同比

ccvgpt 2025-01-09 11:02:09 基础教程 2 ℃

函数定义

add_months(string start_date, int num_months, output_date_format)

返回距离给定 start_date 日期 num_months 个月后的日期。

参数说明

start_date

Hive内置函数add_months()使用详解:计算环比与同比

表示要增加月数的日期,可以是一个字符串、日期或时间戳。

注意,在 Hive 4.0.0 版本之前,函数add_months会忽略日期中的时间部分。如 select add_months('2024-02-09 02:01:56', 1)返回的结果为2024-03-09。

num_months

整数类型,表示要增加的月数,负数表示减去月数,正数表示增加月数。如:

-1 表示减去一个月,+1 表示加上一个月。

output_date_format

可选参数,表示时期输出格式,默认输出格式为 yyyy-MM-dd。

注意,从 Hive 4.0.0 版本开始,add_months 函数增加了一个可选参数 output_date_format,接受一个字符串形式的合法日期格式,以便在输出结果中保留时间格式。

返回类型

string

使用示例

下面的示例演示add_months函数的使用。

SELECT add_months('2024-02-22', 1);     -- 结果为 2024-03-22
SELECT add_months('2024-02-22', -1);    -- 结果为 2024-01-22
SELECT add_months('2024-01-31', 1);     -- 结果为 2024-02-29
SELECT add_months('2024-02-29', 1);     -- 结果为 2024-03-31

计算月环比增长率示例

环比基本概念

环比是与上一个相邻统计周期相比较,表明统计指标逐期的发展变化 , 可以理解为第 n 月与第 n-1 月的比较。如,2019 年 12 月份与 2019 年 11 月份相比较,2019 年 1 月份与 2018 年 12 月份相比较就是环比。环比增长率是指本期和上期相比较的增长率,计算公式为:环比增长率 =(本期数-上期数)/上期数 ×100%。例如,某公司 2019 年 6 月份营业额为 100 万元,为本期数,上期数就是 2019 年 5 月份营业额 80 万元,环比增长率为(100 - 80)/ 80×100% =25%,即某公司 2019 年 6 月份营业额环比增长 25%。

——摘自于国家统计局官网


  1. 数据准备:

创建表:

CREATE TABLE `data.dws_trd_gmv_mth`(
  `mth` string COMMENT '月份', 
  `gmv` string COMMENT 'GMV')
COMMENT '每月GMV记录表'  
ROW FORMAT SERDE 
  'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' 
STORED AS INPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat' 
OUTPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
TBLPROPERTIES (
  'parquet.compression'='SNAPPY')

插入测试数据:

-- 插入数据
INSERT INTO TABLE `data.dws_trd_gmv_mth`
VALUES
	( '202201', 2801638426.44 ),
	( '202202', 1557393326.32 ),
	( '202203', 2212390716.94 ),
	( '202204', 2056446827.58 ),
	( '202205', 2996239586.36 ),
	( '202206', 4384489238.87 ),
	( '202207', 1681752681.46 ),
	( '202208', 2028909730.46 ),
	( '202209', 1987595870.36 ),
	( '202210', 3650957432.00 ),
	( '202211', 5120499796.13 ),
	( '202212', 2769287257.07 ),
	( '202301', 3048485826.70 ),
	( '202302', 1491542000.81 ),
	( '202303', 2547987945.63 ),
	( '202304', 2303809286.98 ),
	( '202305', 2492541948.33 ),
	( '202306', 4605883471.41 ),
	( '202307', 2009134399.26 ),
	( '202308', 2278225413.09 ),
	( '202309', 3563285345.83 ),
	( '202310', 2965688097.08 ),
	( '202311', 5348211112.05 ),
	( '202312', 2851086932.03 );

查询表中的数据:

SELECT mth, gmv FROM `data.dws_trd_gmv_mth`;

/* 查询结果
mth   |gmv          |
------+-------------+
202201|2801638426.44|
202202|1557393326.32|
202203|2212390716.94|
202204|2056446827.58|
202205|2996239586.36|
202206|4384489238.87|
202207|1681752681.46|
202208|2028909730.46|
202209|1987595870.36|
202210|3650957432.00|
202211|5120499796.13|
202212|2769287257.07|
202301|3048485826.70|
202302|1491542000.81|
202303|2547987945.63|
202304|2303809286.98|
202305|2492541948.33|
202306|4605883471.41|
202307|2009134399.26|
202308|2278225413.09|
202309|3563285345.83|
202310|2965688097.08|
202311|5348211112.05|
202312|2851086932.03|
*/
  1. 计算环比:

因为表data.dws_trd_gmv_mth的月份数据格式不是yyyy-MM-dd的日期格式,所以在使用add_months 函数计算环比之前,需要将月份转换为格式yyyy-MM-dd。可以结合使用from_unixtime函数与unix_timestamp函数进行格式转换:

SELECT from_unixtime( unix_timestamp(mth ,'yyyyMM'),'yyyy-MM-01') FROM `data.dws_trd_gmv_mth`;

/* 查询结果
_c0       |
----------+
2022-01-01|
2022-02-01|
2022-03-01|
2022-04-01|
2022-05-01|
2022-06-01|
2022-07-01|
2022-08-01|
2022-09-01|
2022-10-01|
2022-11-01|
2022-12-01|
2023-01-01|
2023-02-01|
2023-03-01|
2023-04-01|
2023-05-01|
2023-06-01|
2023-07-01|
2023-08-01|
2023-09-01|
2023-10-01|
2023-11-01|
2023-12-01|
*/

通过LEFT JOIN的方式将本期数据与上期数据进行关联,其中左表为本期数据,右表为上期数据。即将 2022 年 2 月的数据与 2022 年 1 月的数据进行关联,2022 年 3 月的数据与 2022 年 2 月的数据进行关联,以此类推。具体 SQL 如下:

SELECT
	t1.mth,
	(t1.gmv - t2.gmv) / t2.gmv * 100
FROM
	`data.dws_trd_gmv_mth` t1
LEFT JOIN `data.dws_trd_gmv_mth` t2 
	ON from_unixtime(unix_timestamp(t1.mth, 'yyyyMM'), 'yyyy-MM-01') = add_months(from_unixtime(unix_timestamp(t2.mth, 'yyyyMM'), 'yyyy-MM-01'), 1);

/* 查询结果
mth   |_c1                |
------+-------------------+
202201|                   |
202202| -44.41133760793836|
202203|  42.05728761967334|
202204| -7.048659541280715|
202205|  45.69983265193082|
202206|  46.33306558093117|
202207| -61.64313355930524|
202208|  20.64257443006533|
202209|-2.0362591533647656|
202210|   83.6871109688272|
202211| 40.250876420790874|
202212|-45.917637587584956|
202301|  10.08196491415633|
202302| -51.07269360590726|
202303|  70.82911136570638|
202304| -9.583195205800942|
202305|  8.192199867264376|
202306|  84.78659805488674|
202307| -56.37895722435757|
202308| 13.393380449267664|
202309|  56.40618023819902|
202310| -16.77096248969646|
202311|  80.33626386118686|
202312|-46.690830404838636|
*/

对环比值进行四舍五入操作,并保留两位小数,同时在环比值后面添加百分号(%):

SELECT
	t1.mth,
	concat(round((t1.gmv - t2.gmv) / t2.gmv * 100, 2), '%')
FROM
	`data.dws_trd_gmv_mth` t1
LEFT JOIN `data.dws_trd_gmv_mth` t2 
	ON from_unixtime(unix_timestamp(t1.mth, 'yyyyMM'), 'yyyy-MM-01') = add_months(from_unixtime(unix_timestamp(t2.mth, 'yyyyMM'), 'yyyy-MM-01'), 1);

/*
mth   |_c1    |
------+-------+
202201|       |
202202|-44.41%|
202203|42.06% |
202204|-7.05% |
202205|45.7%  |
202206|46.33% |
202207|-61.64%|
202208|20.64% |
202209|-2.04% |
202210|83.69% |
202211|40.25% |
202212|-45.92%|
202301|10.08% |
202302|-51.07%|
202303|70.83% |
202304|-9.58% |
202305|8.19%  |
202306|84.79% |
202307|-56.38%|
202308|13.39% |
202309|56.41% |
202310|-16.77%|
202311|80.34% |
202312|-46.69%|
*/

计算月同比增长率示例

同比基本概念

同比是以上年同期为基期相比较,即本期某一时间段与上年某一时间段相比, 可以理解为今年第 n 月与去年第 n 月的比较。如,2019 年 12 月份与 2018 年 12 月份相比较,2019 年上半年与 2018 年上半年相比较就是同比。同比增长率是指本期和上一年同期相比较的增长率,计算公式为:同比增长率=(本期数-同期数)/同期数×100%。例如,某公司 2019 年上半年利润 3000 万元,为本期数, 同期数就是 2018 年上半年的利润 2000 万元,同比增长率为(3000 - 2000)/ 2000×100% = 50%,即某公司 2019 年上半年利润同比增长 50%。

——摘自于国家统计局官网

计算月同比的逻辑与计算月环比的逻辑是差不多的,区别在于环比的计算是本期数与上月(即相差 1 个月)的期数进行相比,而同比的计算是本期数与上年(即相差 12 个月)同期的期数进行相比。即将 2023 年 1 月的数据与 2022 年 1 月的数据相比,2023 年 2 月的数据与 2022 年 2 月的数据进相比,以此类推。具体 SQL 如下:

-- 与计算环比的SQL类似,只是关联条件是加了12个月
SELECT
	t1.mth,
	concat(round((t1.gmv - t2.gmv) / t2.gmv * 100, 2), '%')
FROM
	`data.dws_trd_gmv_mth` t1
LEFT JOIN `data.dws_trd_gmv_mth` t2 
	ON from_unixtime(unix_timestamp(t1.mth, 'yyyyMM'), 'yyyy-MM-01') = add_months(from_unixtime(unix_timestamp(t2.mth, 'yyyyMM'), 'yyyy-MM-01'), 12);

/* 查询结果
mth   |_c1    |
------+-------+
202201|       |
202202|       |
202203|       |
202204|       |
202205|       |
202206|       |
202207|       |
202208|       |
202209|       |
202210|       |
202211|       |
202212|       |
202301|8.81%  |
202302|-4.23% |
202303|15.17% |
202304|12.03% |
202305|-16.81%|
202306|5.05%  |
202307|19.47% |
202308|12.29% |
202309|79.28% |
202310|-18.77%|
202311|4.45%  |
202312|2.95%  |
*/

注解

如果start_date的日期是月份的最后一天,或者所得到的月份天数少于start_date的天数部分,则结果日期为所得月份的最后一天。否则,结果日期与start_date具有相同的天数部分。

例如,当start_date值为 2024 年 2 月的最后一天时,即2024-02-29,使用add_months函数加一个月,输出的日期为 2024 年 3 月的最后一天,即2024-03-31。

当start_date值为 2024 年 1 月 30 号时,即2024-01-30,使用add_months函数加一个月,输出的日期为 2024 年 2 月的最后一天,即2024-02-29。

适用于

从 Hive 1.1.0 版本开始支持。

最近发表
标签列表