clickhouse--求累计数值


参考:
clickhouse–行列转换
clickhouse–开窗函数

数据准备

create table test.test_accum(
	pkg String,
	day String,
	region_0 UInt32,
	region_1 UInt32,
	region_2 UInt32
) ENGINE = MergeTree()
ORDER BY pkg

向数据表中插入数据:

INSERT INTO test.test_accum VALUES
('pkg1', '20220510', 1000, 2000, 3000),
('pkg1', '20220511', 1000, 2000, 3000),
('pkg1', '20220512', 1000, 2000, 3000),
('pkg1', '20220513', 1000, 2000, 3000),
('pkg1', '20220411', 1000, 2000, 3000),
('pkg1', '20220412', 1000, 2000, 3000),
('pkg2', '20220510', 1000, 2000, 3000),
('pkg2', '20220511', 2000, 3000, 3000),
('pkg2', '20220512', 1000, 3000, 3000),
('pkg2', '20220513', 3000, 2000, 3000)

查询数据,得到结果:

┌─pkg──┬─day──────┬─region_0─┬─region_1─┬─region_2─┐
│ pkg1 │ 20220510 │     1000 │     2000 │     3000 │
│ pkg1 │ 20220511 │     1000 │     2000 │     3000 │
│ pkg1 │ 20220512 │     1000 │     2000 │     3000 │
│ pkg1 │ 20220513 │     1000 │     2000 │     3000 │
│ pkg1 │ 20220411 │     1000 │     2000 │     3000 │
│ pkg1 │ 20220412 │     1000 │     2000 │     3000 │
│ pkg2 │ 20220510 │     1000 │     2000 │     3000 │
│ pkg2 │ 20220511 │     2000 │     3000 │     3000 │
│ pkg2 │ 20220512 │     1000 │     3000 │     3000 │
│ pkg2 │ 20220513 │     3000 │     2000 │     3000 │
└──────┴──────────┴──────────┴──────────┴──────────┘

数据需求

希望按照APP来统计不同区间内数值的百分比,同时也需要计算按照区间递增的累计百分比。预期结果如下:

┌─pkg──┬─region───┬─value─┬───────value_percent─┬───────accum_percent─┐
│ pkg1 │ region_0 │  6000 │ 0.16666666666666666 │ 0.16666666666666666 │
│ pkg1 │ region_1 │ 12000 │  0.3333333333333333 │                 0.5 │
│ pkg1 │ region_2 │ 18000 │                 0.5 │                   1 │
│ pkg2 │ region_0 │  7000 │  0.2413793103448276 │  0.2413793103448276 │
│ pkg2 │ region_1 │ 10000 │  0.3448275862068966 │  0.5862068965517241 │
│ pkg2 │ region_2 │ 12000 │ 0.41379310344827586 │                   1 │
└──────┴──────────┴───────┴─────────────────────┴─────────────────────┘

实现方法

arraySum

我们的思路是先将数据初步统计,然后进行数组压缩,得到数组以后使用array join进行展开。而在展开的过程中,通过arraySlice不断获取数组的一部分子集,然后用arraySum对子集进行求和,从而得到最终的累计值。

select
	pkg,
	region,
	value,
	value/sum_value value_percent,
	arraySum(arraySlice(value_arr, 1, num))/sum_value accum_percent
from
	(select
		pkg,
		region_0 + region_1 + region_2 as sum_value,
		array(region_0, region_1, region_2) as value_arr
	from
		(select 
			pkg,
			sum(region_0) as region_0,
			sum(region_1) as region_1,
			sum(region_2) as region_2
		from test.test_accum
		group by pkg
		) aa
	) bb
array join
	['region_0', 'region_1', 'region_2'] as region,
	value_arr as value,
	arrayEnumerate(value_arr) AS num

结果如下:

┌─pkg──┬─region───┬─value─┬───────value_percent─┬───────accum_percent─┐
│ pkg1 │ region_0 │  6000 │ 0.16666666666666666 │ 0.16666666666666666 │
│ pkg1 │ region_1 │ 12000 │  0.3333333333333333 │                 0.5 │
│ pkg1 │ region_2 │ 18000 │                 0.5 │                   1 │
│ pkg2 │ region_0 │  7000 │  0.2413793103448276 │  0.2413793103448276 │
│ pkg2 │ region_1 │ 10000 │  0.3448275862068966 │  0.5862068965517241 │
│ pkg2 │ region_2 │ 12000 │ 0.41379310344827586 │                   1 │
└──────┴──────────┴───────┴─────────────────────┴─────────────────────┘

arrayCumSum

前一种方法要不断对数组进行切割,我们其实也可以直接使用arrayCumSum获取数组的每个元素到当前遍历元素的所有元素和,从而得到目标累计值。

select
	pkg,
	region,
	value,
	value/sum_value value_percent,
	value_accum/sum_value accum_percent
from
	(select
		pkg,
		region_0 + region_1 + region_2 as sum_value,
		array(region_0, region_1, region_2) as value_arr,
		arrayCumSum(array(region_0, region_1, region_2)) as value_accum
	from
		(select 
			pkg,
			sum(region_0) as region_0,
			sum(region_1) as region_1,
			sum(region_2) as region_2
		from test.test_accum
		group by pkg
		) aa
	) bb
array join
	['region_0', 'region_1', 'region_2'] as region,
	value_arr as value,
	value_accum

结果如下:

┌─pkg──┬─region───┬─value─┬───────value_percent─┬───────accum_percent─┐
│ pkg1 │ region_0 │  6000 │ 0.16666666666666666 │ 0.16666666666666666 │
│ pkg1 │ region_1 │ 12000 │  0.3333333333333333 │                 0.5 │
│ pkg1 │ region_2 │ 18000 │                 0.5 │                   1 │
│ pkg2 │ region_0 │  7000 │  0.2413793103448276 │  0.2413793103448276 │
│ pkg2 │ region_1 │ 10000 │  0.3448275862068966 │  0.5862068965517241 │
│ pkg2 │ region_2 │ 12000 │ 0.41379310344827586 │                   1 │
└──────┴──────────┴───────┴─────────────────────┴─────────────────────┘

开窗

除了上述两种方法,也可以使用开窗函数进行累计值的获取,如下所示;

select
	pkg,
	region,
	value,
	value/sum_value value_percent,
	sum(value/sum_value) over win as accum_percent
from
	(select
		pkg,
		region_0 + region_1 + region_2 as sum_value,
		array(region_0, region_1, region_2) as value_arr
	from
		(select 
			pkg,
			sum(region_0) as region_0,
			sum(region_1) as region_1,
			sum(region_2) as region_2
		from test.test_accum
		group by pkg
		) aa
	) bb
array join
	['region_0', 'region_1', 'region_2'] as region,
	value_arr as value
WINDOW win as (partition by pkg ORDER BY region rows between unbounded preceding and current row)
SETTINGS allow_experimental_window_functions = 1

结果如下:

┌─pkg──┬─region───┬─value─┬───────value_percent─┬───────accum_percent─┐
│ pkg1 │ region_0 │  6000 │ 0.16666666666666666 │ 0.16666666666666666 │
│ pkg1 │ region_1 │ 12000 │  0.3333333333333333 │                 0.5 │
│ pkg1 │ region_2 │ 18000 │                 0.5 │                   1 │
│ pkg2 │ region_0 │  7000 │  0.2413793103448276 │  0.2413793103448276 │
│ pkg2 │ region_1 │ 10000 │  0.3448275862068966 │  0.5862068965517242 │
│ pkg2 │ region_2 │ 12000 │ 0.41379310344827586 │                   1 │
└──────┴──────────┴───────┴─────────────────────┴─────────────────────┘
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据分析职业是一个多金的职业,数据分析职位是一个金饭碗的职位,前景美好,但是要全面掌握大数据分析技术,非常困难,大部分学员的痛点是不能快速找到入门要点,精准快速上手。本课程采用项目驱动的方式,以Spark3和Clickhouse技术为突破口,带领学员快速入门Spark3+Clickhouse数据分析,促使学员成为一名高效且优秀的大数据分析人才。学员通过本课程的学习,不仅可以掌握使用Python3进行Spark3数据分析,还会掌握利用Scala/java进行Spark数据分析,多语言并进,力全面掌握;另外通过项目驱动,掌握Spark框架的精髓,教导Spark源码查看的技巧;会学到Spark性能优化的核心要点,成为企业急缺的数据分析人才;更会通过Clickhouse和Spark搭建OLAP引擎,使学员对大数据生态圈有一个更加全面的认识和能力的综合提升。真实的数据分析项目,学完即可拿来作为自己的项目经验,增加面试谈薪筹码。课程涉及内容:Ø  Spark内核原理(RDD、DataFrame、Dataset、Structed Stream、SparkML、SparkSQL)Ø  Spark离线数据分析(千万简历数据分析、雪花模型离线数仓构建)Ø  Spark特征处理及模型预测Ø  Spark实时数据分析(Structed Stream)原理及实战Ø  Spark+Hive构建离线数据仓库(数仓概念ODS/DWD/DWS/ADS)Ø  Clickhouse核心原理及实战Ø  Clickhouse engine详解Ø  Spark向Clickhouse导入简历数据,进行数据聚合分析Ø  catboost训练房价预测机器学习模型Ø  基于Clickhouse构建机器学习模型利用SQL进行房价预测Ø  Clickhouse集群监控,Nginx反向代理Grafana+Prometheus+Clickhouse+node_exporterØ  Spark性能优化Ø  Spark工程师面试宝典       课程组件:集群监控:福利:本课程凡是消费满359的学员,一律送出价值109元的实体书籍.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值