Birt 如何实现不规则月份统计

错误码
• 阅读 556

业务报表中,常常需要基于时间段进行分组统计,特别是按月份分组统计。一般情况如果按自然月就简单了,但有时候也会需要按不规则月份来分组。例如,某企业从 1 月 16 日开始实行某种特殊的价格策略或营销活动,因此以后都想以每月 16 号为界来统计产品销售情况。这里所谓不规则月份就是指: 如果起始时间是 2013-01-16,则将 2013-01-16 到 2013-02-15 作为一组,将 2013-02-16 到 2013-03-15 作为一组。更特别的,如果起始时间是 2013-01-31,则可能要求将 2013-01-31 到 2013-02-27 作为一组,而将 2013-02-28 到 2013-03-30 作为一组,也就是“从每月最后一天”开始分组。

怎么样?小伙伴们是不是有点傻眼了?对于 Birt 等报表工具,一般都会提供按自然月分组的表达式,但也却都难以应对这种不规则月份分组的表达式。如果要解决这个问题,往往需要编写程序实现自定义报表数据集,而在程序中按这种规则进行分组,不但编程工作量不小,更重要的是基本无法通用。

现在好了,如果在报表工具中引入集算器,解决这个问题就易如反掌了。下面我们就以 Birt 报表工具为例,讲解一下实现的过程。对其它报表工具来说,也基本大同小异。

在本例中,要统计企业从 2013-01-16 日开始到 2013-08-15 结束,每个月的销售总额。数据表 salesall 中原始数据如下:

Birt 如何实现不规则月份统计

最后需要得到如下图所示的目标表样:

Birt 如何实现不规则月份统计

我们直接来看集算器解决这个问题的 SPL 代码:

Birt 如何实现不规则月份统计

A1   连接数据库

A2   从数据库订单表中查出统计开始日期到结束日期之间的订单数据,startDate 和 endDate 是日期参数。

A3   根据起止时间算出月份间隔,比如 2013-01-16 和 2013-08-15 间隔 7 个月。

B3   根据起始时间和日期间隔算出不规则月份的开始日期,并将起始时间插入第 1 位。“|”表示合并,“~”表示集合中的当前成员,即数字 1 到 7,结合不同的选项,elapse 函数可以正确计算各种不规则月份的情况。

A4   按 B3 区间对 A2 分组,统计出不规则月份的销售额,保留两位小数,并将 B3 作为最后一列。函数 pseg 可返回参数,也就是订购日期所在的区间号。~.sum(Amount)中的~表示分组后的当前组。# 表示 A2 当前组号。

A5   取出 A4 的组号作为 Number,第 2 列为 TotalAmount,第 3 列为分组的 StartDate,生成新的结果序表。

A6   关闭数据库

A7   将 A5 作为数据集返回给报表工具。

将集算器 SPL 代码存为 orders.dfx 文件,然后引入到 Birt 报表中。如何引入请参看乾学院文章《BIRT 调用 SPL 脚本》。

在 BIRT 中设计简单的 list 表如下:

Birt 如何实现不规则月份统计

报表调用集算器的方法和调用存储过程完全一样,比如在 BIRT 的存储过程数据集中可以用 call orders(?,?) 来调用。输入开始日期参数 2013-01-16、结束日期参数 2013-08-15 后,预览报表就可以看到要求的目标表样了。

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
java操作 mongodb 进行 按天、周、月分组统计
publicList<PlaybackEntityqueryPlaybackRecord(FunctionUseQueryEntityqueryEntity){CriteriacriteriaCriteria.where("createTime").gte(queryEntity.getStartTime()).lte(
Stella981 Stella981
3年前
Jieba分词Python简单实现
上一章分享了IKAnalyzer中文分词及词频统计基于Hadoop的MapReducer框架Java实现。这次将与大家分享Jieba中文分词Python简单实现,由于Jieba分词是基于词频最大切分组合,所以不用做词频统计,可以直接得到其关键字。1、安装jieba安装方式可以查看博主的中文分词工具(http://my.oschina.net/ea
Wesley13 Wesley13
3年前
Java简单实现滑动窗口
由于最近有一个统计单位时间内某key的访问次数的需求,譬如每5秒访问了redis的某key超过100次,就取出该key单独处理。这样的单位时间统计,很明显我们都知道有个边界问题,譬如5秒内100次的限制。刚好前4.99秒访问都是0,最后0.01秒来了100次,5.01秒又来了100次。也就是访问有明显的毛刺情况出现,为了弱化这个毛刺情况,我们可以采用滑动
Wesley13 Wesley13
3年前
Java日期时间API系列22
  Java8中为月份和星期新增的了,Month和DayOfWeek,来处理月份和星期的特殊问题,这2个类都是枚举类,对Month、DayOfWeek源码说明和简单应用,月份英文,月份英文简称,月份中文,星期英文,星期英文简称,星期中文等。1.Month1.1部分源码:\@implSpec\Thisisan
Stella981 Stella981
3年前
Hive 练习 简单任务处理
1、2018年4月份的用户数、订单量、销量、GMV (不局限与这些统计量,你也可以自己想一些)2018年4月份的用户数量selectcount(a.user_id)asuser_numsfrom(selectuser_idfrom
Wesley13 Wesley13
3年前
mongo14
group,aggregate,mapReduce分组统计:group()简单聚合:aggregate()强大统计:mapReduce()db.collection.group(document)document:{key:{key
Wesley13 Wesley13
3年前
mysql——GROUP BY和HAVING
GROUPBY语法可以根据给定数据列的每个成员对查询结果进行分组统计,最终得到一个分组汇总表。select子句中的列名必须为分组列或列函数,列函数对于groupby子句定义的每个组返回一个结果。某个员工信息表结构和数据如下:  id  name  dept  salary  edlevel     hiredate   1  张
Wesley13 Wesley13
3年前
Java日期时间API系列23
  有时候,往往需要统计某个时间区间的销量等问题,这就需要准确的起始时间,获取准确开始时间00:00:00,获取准确结束时间23:59:59。下面增加了一一些方法,获取当天起始时间,昨天起始时间,当前月第一天开始时间,当前月最后一天结束时间,上个月第一天开始时间,上个月最后一天结束时间,某个指定月的起始结束时间等等。其中月份最后一天往往因为月份不同和
Stella981 Stella981
3年前
Monogdb使用 MapReduce进行分组统计查询
/      @param businessNo    @param beginTime 开始时间   @param endTime 结束时间   @param pageNo  页码   @param pageSiz
Wesley13 Wesley13
3年前
mysql数据行转列
在你找工作的经历当中,是否有面试官问过你:数据库行转列如何实现? 一个典型的例子如下:    有这样一个订单表(om\_order)一条记录包含订单号、创建日期、订单总金额; 让你统计不同年份对应各月份的销售情况,要求每一年的销售情况一行展示,效果如下:
混世魔王 混世魔王
2年前
皕杰报表之数据集函数
所谓数据集函数就是与数据集相关,从数据集取数的函数。这些函数不仅可以将数据直接从数据集取出,而且可以将取出的数据分组、求和、求最大值最小值、求第一条数据和最后一条数据、求前n条数据以及对取出的数据进行按段分割,还能对列和记录进行统计。在皕杰报表中共提供了1