使用Jasper或BIRT等报表工具时,常会碰到一些非常规的统计,用报表工具本身或SQL都难以处理,比如源数据中有条特殊数据,其他数据都要和它进行占比、求和等计算。集算器具有结构化强计算引擎,集成简单,可以协助报表工具方便地实现此类需求。下面通过一个例子来说明不规则跨行计算报表的实现过程。
数据库表majorSum存储着某医院重点科室以及全院的患者统计,报表需要按字母顺序呈现各科室的患者占比,并在最后保留全院患者数量。源数据如下:
期望的报表如下:
department | patient |
Accident and emergency (A&E) | 7.03% |
Anaesthetics | 12.37% |
Breast screening | 12.37% |
Discharge lounge | 14.61% |
Ear nose and throat | 15.06% |
Haematology | 17.43% |
Neurology | 5.23% |
Cardinal Community Hospital | 44562 |
集算器可以准备出报表需要的数据,代码如下:
A1=myDB1.query(“select department,patient from majorSum order by department”)
执行SQL,在数据源myDB1中检索majorSum表,结果如下:
A2=A1.maxp(patient)
取出全院患者所在的记录,函数maxp可以取出字段值最大的记录,即Cardinal Community Hospital。
A3=A1\A2
从完整记录A1中去除全院记录A2,运算符“\”可求出集合间的差集。
A4=A3.run(string(patient/A2.patient,”#.##%”):patient)
计算各科室患者的占比。函数run可对A3进行循环计算,函数string可将数字格式化为字符串。结果如下:
A5=A4|A2
将全院记录和占比数据合并。运算符“|”相当于函数union。集算器支持泛型二维表,因此字符串和数字可以存储在同一个字段。A5的计算结果就是报表需要的数据,如下:
A6:result A5
将A5返回给报表工具。集算器对外提供JDBC接口,报表工具会将集算器识别为普通数据库,集成方案请参考相关文档。
上述代码是分步计算,便于观察中间结果,熟练后可以简化为下面两句代码:
A1=myDB1.query(“select department,patient from majorSum order by department”);
A2:result(total=A1.maxp(patient),(A1\total).run(string(patient/total.patient,”#.##%”):patient)|total)
接下来以BIRT为例设计一张简单的list表,模板如下:
预览后可以看到报表结果:
报表调用集算器的方法和调用存储过程一样,比如将本脚本保存为irregulProportion.dfx,则在BIRT的存储过程设计器中可以用call irregulProportion()来调用。同样地,集算器也支持报表参数。