目录

  • 数据准备
  • 数据需求
  • 实现方法
    • arraySum
    • arrayCumSum
    • 开窗

参考:
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对子集进行求和,从而得到最终的累计值。

selectpkg,region,value,value/sum_value value_percent,arraySum(arraySlice(value_arr, 1, num))/sum_value accum_percent
from(selectpkg,region_0 + region_1 + region_2 as sum_value,array(region_0, region_1, region_2) as value_arrfrom(select pkg,sum(region_0) as region_0,sum(region_1) as region_1,sum(region_2) as region_2from test.test_accumgroup 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获取数组的每个元素到当前遍历元素的所有元素和,从而得到目标累计值。

selectpkg,region,value,value/sum_value value_percent,value_accum/sum_value accum_percent
from(selectpkg,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_accumfrom(select pkg,sum(region_0) as region_0,sum(region_1) as region_1,sum(region_2) as region_2from test.test_accumgroup 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 │
└──────┴──────────┴───────┴─────────────────────┴─────────────────────┘

开窗

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

selectpkg,region,value,value/sum_value value_percent,sum(value/sum_value) over win as accum_percent
from(selectpkg,region_0 + region_1 + region_2 as sum_value,array(region_0, region_1, region_2) as value_arrfrom(select pkg,sum(region_0) as region_0,sum(region_1) as region_1,sum(region_2) as region_2from test.test_accumgroup 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 │
└──────┴──────────┴───────┴─────────────────────┴─────────────────────┘

clickhouse--求累计数值相关推荐

  1. c语言学习-在一个三行三列的矩阵中求出数值最大的元素及其行/列下标并打印输出

    在一个三行三列的矩阵中求出数值最大的元素及其行/列下标并打印输出 程序流程图: 代码: #include<stdio.h> void main() {int a[3][3]; int i= ...

  2. 按公式 s=12+22+32+...+n2,求累计加和,s 不超过 1000 的最大项数

    按公式 s=12+22+32+-+n2,求累计加和,s 不超过 1000 的最大项数 按公式 s=12+22+32+-+n2,求累计加和,s 不超过 1000 的最大项数 n,程序运 行结果如下所示: ...

  3. matlab求微分数值,用MATLAB语言求微积分方程的数值解.(xd^2y)/dx^2-5dy/dx+y=0y(0)=0y'(0)=0...

    function dy=myfun03(x,y) dy=zeros(3,1) %初始化变量dy dy(1)=y(2); %dy(1)表示y的一阶导数,其等于y的第二列值 dy(2)=5/x*y(3)- ...

  4. php 数值相加_php – 合并2个数组并求值(数值键)

    我有2个阵列 Array ( [010156] => Array ( [supp_number] => 010156 [totalamount] => 4.113,23 [debto ...

  5. Clickhouse求时间差

    dateDiff 函数:返回两个Date或DateTime类型之间的时差. #语法 dateDiff('unit', startdate, enddate, [timezone])#参数解释 unit ...

  6. Pandas-数据操作-数值型(二):累计统计函数【cumsum、cumprod、cummax、cummin】【计算前1/2/3/…/n个数的和、积、最大值、最小值】

    一.累计统计函数 函数 作用 cumsum 计算前1/2/3/-/n个数的和 cummax 计算前1/2/3/-/n个数的最大值 cummin 计算前1/2/3/-/n个数的最小值 cumprod 计 ...

  7. Pandas学习(三)---数值运算

    Pandas学习--数值运算 数值计算和统计基础 常用数学.统计方法 基本参数:axis.skipna 主要数学计算方法,可用于Series和DataFrame(1) 主要数学计算方法,可用于Seri ...

  8. matlab实验二数值运算报告,MATLAB数值运算实验报告.docx

    MATLAB数值运算实验报告 实验报告系 (部): 信息工程 班 级: 姓 名: 学 号: 课 程: MATLAB 实验名称: Matlab数值运算目录一 . 实验目的2二 . 实验内容2三 . 实验 ...

  9. php求平均值的函数_国二常用函数(二)

    二.统计函数 1.Count函数:统计单元格的个数,参数必须是数值. 函数格式:=Count(数值 1,数值 2,-) 应用举例说明: =COUNT(B1:B10)表示统计单元格区域B1到B10中包含 ...

最新文章

  1. 微软拼音输入法2007状态栏无法显示!
  2. muduo之Connector
  3. 基因分子生物学(2)-DNA携带遗传特性
  4. boost::search相关的测试程序
  5. HTML5获取autoComplete属性:告诉浏览器是否记录之前的输入值
  6. 牛客ACM赛 B [小a的旅行计划 ]
  7. 1/7 SELECT语句:基础检索
  8. 【原创】什么是 wire protocol
  9. Hamcrest总结--思维导图
  10. cdate在java中_Java Calendar.add方法代码示例
  11. 单片机歌曲代码大全_对于 51 单片机的四大误区!
  12. 微信怎样设置聊天显示的字体大小?简单技巧!微信如何调整字体的大小?
  13. 朗兰兹纲领:关于数学大一统的伟大构想
  14. 怎样把m4a转换mp3格式?
  15. cura切片操作学习
  16. 《创业时代》,不带你们这样黑程序员的
  17. 蓝牙快速连接 android,Android智能设备快速连接蓝牙的方法与流程
  18. matlab生成高速轨道不平顺谱,国内外高速铁路轨道不平顺谱对比与思考.pdf
  19. 大数据入门教程,小白快速掌握Hadoop集成Kerberos安全技术
  20. 用科技赋能教育创新与重构 华为将教育信息化落到实处

热门文章

  1. gulp仿移动端网易云音乐播放界面
  2. opencv-python(cv2)——如何读取和保存中文路径图片(含代码)
  3. Python实现Excel办公自动化
  4. 编译原理:算符优先分析实验
  5. 工业相机(高速相机)与普通相机的差别
  6. Suker的进球庆祝动作
  7. ctrl键频繁失灵,但不是键盘本身的问题,换个键盘同样失灵
  8. 抖音运营从内容开始做起,抖音内容创作
  9. 关于移位密码的破解问题
  10. axios每次发送请求会有两次,多一次Request Method: OPTIONS是怎么回事?