润乾报表分组求和_润乾集算报表非常规统计之按段分组.pdf

润乾集算报表非常规统计之按段分组

润乾集算报表非常规统计之按段分组

报表开发中,经常会碰到一些需要进行非常规统计的报表,固定分组、可重复分组、组

内排序,还包括跨行组计算的报表,甚至有些报表本身无数据来源、以及需要对数据源再计

算。这些报表本身具备一定的特殊性,使用常规方法往往难于实现。

对于按段分组报表,各段之间可以有重复,也就可能出现按段可重复的分组报表。集算

报表在完成这类特殊统计报表时比较简单,这里通过一个实例说明实现过程。

报表说明

根据员工基本信息表按年龄统计各年龄段区间的人数、奖金等汇总情况。报表样式如下:

这里“30-40 岁”和“35-45”岁两个区间是有重复的。下面来对比一下润乾报表和集算报表实

现上的差异。

这个报表的麻烦之处在于需要进行的分组是有重复的,报表要完成较复杂的数据计算工

作,但一般报表工具的计算能力较弱,如果采用报表工具本身来完成这个计算工作则会相当

复杂,比如采用用润乾报表来实现将会是这样的:

在润乾报表中,该类报表主要通过ds.enumGroup()函数完成,报表模板及表达式如下:

其中A2 单元格表达式为:

=ds1.enumGroup(true,age(BIRTHDAY)>20&&age(BIRTHDAY)<=30,"20 岁 到 30 岁

",age(BIRTHDAY)>30&&age(BIRTHDAY)<=40,"30 岁 到 40 岁

",age(BIRTHDAY)>=35&&age(BIRTHDAY)<45,"35 岁到45 岁", age(BIRTHDAY)>=45,"45 岁以上")

润乾报表在实现上使用了ds.enumGroup()函数,在分组较少的时候做起来比较简单,这

也是其他报表工具无法比拟润乾报表的方面。但当分组较多,计算比较复杂的情况下,润乾

报表实现起来就比较困难了。原因在于报表的数据源准备和呈现混在一起导致的,往往需要

在报表模板中实现大量的计算任务,如果将这两部分分开,即:独立的计算层负责数据源准

备(完成复杂计算)和独立的展现层负责报表呈现,则会使报表开发变得更加清晰。

所以,另一种办法是事先把数据计算准备好,报表工具只需要负责呈现和简单计算。但

无论是使用复杂 SQL 、存储过程和自定义JAVA 数据集编程,对于这样的复杂运算(实际情

况往往比这个例子更麻烦得多)都是一件工作量很大的事情,而且难以维护。

集算报表本身内置了适合结构化计算的脚本,可以方便地写出数据准备的计算(相当于

一种更使用更简单的自定义数据集)。上述报表需求使用集算报表可以这样完成:

使用集算报表实现

编写集算脚本

使用集算脚本编辑器编写集算脚本,新建数据源demo2

编写脚本完成按段分组汇总计算

A

1 =connect("demo2")

2 =A1.query("select * from employee")

3 =A2.derive(age(BIRTHDAY):AGE)

[?>=20 && ?<30,?>=30 && ?<40,?>=35

4

&& ?<45,?>=45]

5 [20 到30 岁,30 到40 岁,35 到45 岁,45 岁以上]

6 =A3.enum@r(A4,AGE)

=A6.new(A5(#): 区间,~.count(): 人数,~.sum(SALARY): 合

7 计工资,~.sum(BONUS): 合计奖金,~.sum(ALLOWANCE):

合计补贴)

8 result A7

A1:连接数据源demo2

A2 :取员工表数据

A3:增加日期字段,并根据出生日期计算填充

A4-A5 :指定分段区间以及区间名称,这里A4 和A5 内容可以通过参数传递

A6 :按照给定年龄段完成分组,A.enum()函数提供了@r 选项,允许分组中有重复

A7 :汇总员工工资、奖金等数据

A8 :为报表返回结果集

编辑报表模板

使用集算报表编辑器,设置数据源,用于报表预览

新建报表模板并设置集算器数据集,调用上述编辑好的脚本文件

其中,dfx 文件路径既可以是绝对路径,也可以是相对路径,相对路径是相对选项中配

置的dfx 主目录的。

报表模板及表达式如下

可以看到,使用集算器脚本可以快速完成这类特殊的分组报表。而

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Java8中,可以使用Stream API中的groupingBy方法进行多字分组求和。下面是一个示例代码: 假设有一个包含以下数据的List: ``` List<Record> records = Arrays.asList( new Record("A", "X", 10), new Record("A", "Y", 20), new Record("B", "X", 30), new Record("B", "Y", 40) ); ``` 其中Record为以下类: ``` class Record { private String group1; private String group2; private int value; public Record(String group1, String group2, int value) { this.group1 = group1; this.group2 = group2; this.value = value; } public String getGroup1() { return group1; } public String getGroup2() { return group2; } public int getValue() { return value; } } ``` 如果要按group1和group2字进行分组,并对value字求和,可以使用以下代码: ``` Map<String, Map<String, Integer>> result = records.stream() .collect(Collectors.groupingBy(Record::getGroup1, Collectors.groupingBy(Record::getGroup2, Collectors.summingInt(Record::getValue)))); ``` 这将返回一个Map,其中第一层Map的键为group1字的值,第二层Map的键为group2字的值,值为对应的value字求和的结果。例如,上面的示例代码将返回以下Map: ``` { "A": { "X": 10, "Y": 20 }, "B": { "X": 30, "Y": 40 } } ``` 在以上示例中,我们使用了两个groupingBy方法进行多字分组,第一个groupingBy方法根据group1字进行分组,第二个groupingBy方法根据group2字进行分组,并在最后一个参数中使用summingInt方法对value字求和

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值