双区间交叉报表的制作

使用Jasper或BIRT等报表工具时,常会碰到一些非常规的统计,用报表工具本身或SQL都难以处理,比如交叉表的行组和列组都是分段区间,测度(measurem)来自其他数据库表。集算器具有结构化强计算引擎,集成简单,可以协助报表工具方便地实现此类需求。下面通过一个例子来说明双区间交叉表的实现过程。

表account_detail的主键为account_no,与表Paysoft_result和NAEDO都是1对多关系。Paysoft_result的外键是custno,NAEDO的外键是customer_code。报表要求将account_detail的字段empirica_score按照外部参数分段,作为行组,字段mfin_score同样按照外部参数分段,作为列组。测度的算法是:分组交叉处account_no对应的Paysoft_result表的记录数除以account_no对应的NAEDO表的记录数。

下图是库表间关系,以及字段和报表的关系:

先用集算器准备数据,代码如下:

A1=myDB1.query(“select * from account_detail order by empirica_score,mfin_score”)

上述代码可以从account_detail表取出数据。myDB1是数据源的名字,指向数据库。函数query执行SQL查询。A1的计算结果如下:

A2=myDB1.query(“select * from paysoft_result”)

B2=myDB1.query(“select * from NAEDO”)

类似地,A2和B2分别从paysoft_result表和NAEDO表取出数据,结果如下:

A3=rowList.array()

B3=colList.array()

这两句代码将来自报表的参数转为集算器序列。参数rowList表示行组,比如”560,575,585,595,605,615,625,635,645,654,665”是10个连续区间,参数colList表示列组,比如“39,66,91,116,137,155”是5个连续区间。函数array可将逗号分割的字符串转为序列,转换结果如下:

A4=A1.select(empirica_score>=A3(1) && mfin_score>=B3(1))

本案例的数据超出了区间范围,比如“No501”号客户的empirica_sore等于540,比区间下限560还要小。为了提高性能并简化表达式,可以在A4中过滤掉小于区间下限的数据。

函数select可以进行数据查询或过滤,empirica_score是A1中的字段,A3(1)表示A3的第1个成员,即区间下限560,逻辑运算符“&&”表示“与”。A4的计算结果如下:

A5=A4.group(A3.pselect(empirica_score<~[1]):row,

B3.pselect(mfin_score<~[1]):col;~:accounts,

A2.select(accounts.(account_no).pselect(~==custno)):p,

B2.select(accounts.(account_no).pselect(~==customer_code)):n

)

这句代码对A4(account_detail)按照A3(rowList)和B3(colList)中的区间进行分组,并找出各组数据在A2(paysoft_result)和B2(NAEDO)中对应的记录。

函数group可对数据按照多个字段(或分组标准)进行分组,形如A.group(field1,field2…),也可对分组后的每组数据进行统计或再计算,形如A.group(field1,field2… ; subtotal1,subtotal2…)。分组后各字段可用“:new name”进行重命名,上述分组结果就有5个字段,分别为row,col,accounts,p,n。结果如下:

分组标准row的算法:对A4中的empirica_score字段按照A3中的区间进行分组,代码为:A3.pselect(empirica_score<~[1])。函数pselect可以选出A3中符合条件的成员序号,其中符号“~”表示A3的当前成员,上一个成员用~[-1]来表示,下一个成员用~[1]来表示。当前区间应当是(empirica_score>=~
&& empirica_score<~[1]),由于A4已经在区间下限之上,因此表达式可以简化为empirica_score<~[1]。比如”560,575,585,595,605,615,625,635,645,654,665”可以将A1分到10个区间:560-574,575-584,585-594,595-604,605-614,615-624,625-634,635-644,645-654,655-664,组号分别是1到10。

分组标准col的算法类似:对A4中的mfin_score字段按照B3中的区间进行分组,代码为B3.pselect(mfin_score<~[1])。比如“39,66,91,116,137,155”可将A1分到5个区间:39-65,66-90,91-115,116-136,137-154,组号分别是1到5。

汇总字段account直接取出分组后的各组数据,其中~表示当前组的成员。点击accounts列的蓝色字体可以看到组内成员,其中“row=1,col=1”表示双区间“560-574,39-65”,“row=2,col=5”表示双区间“575-584,137-154”,如下图:

汇总字段P的算法:从A2中找出accounts里对应的记录,代码为:A2.select(accounts.(account_no).pselect(~==custno))。函数select可以按照条件对A2进行查询,找到符合条件的记录。其中“row=1,col=1”、“row=2,col=5”时p列对应的记录如下(accounts和A2是1对多的关系):

汇总字段n的算法类似:从B2中找出accounts里对应的记录,代码为:B2.select(accounts.(account_no).pselect(~==customer_code))。其中“row=1,col=1”、“row=2,col=5”时n列对应的记录如下:

A6=A5.derive(p.count():pCount,n.count():nCount)

这句代码在A5中增加新列pCount,nCount,用来计算每组数据中p和n的记录数,计算结果如下:

A7=A6.derive(pCount/nCount:rate)

这句代码在A6中增加新列rate,算法是pCount除以nCount,计算结果如下:

A8=A7.run(string(A3(row))+”-”+string(A3(row+1)-1):row,string(B3(col))+”-”+string(B3(col+1)-1):col)

这句代码将row和col中的组号反显为区间,函数run表示对A6中的每个成员(比如row=1,col1=1这一行就是一个成员)进行相同的计算。函数string可将数字转为字符串。表达式“A3()”可以根据序号从A3中取出成员,比如A3(1)等于560。A7的计算结果如下:

A8中已经包含了报表需要的三个字段,下面只需将row、col、rate组成新的二维表,并通过JDBC接口返回报表工具,即A9中的代码: result A8.new(row,col,rate)。

函数new可以从A8取出指定的列或计算列,并组成新的二维表,A8.new(row,col,rate)的计算结果如下:

值得注意的是:集算器具有括号运算符,可以对逗号分隔的表达式依次计算,并返回最后一个表达式的值。利用括号运算符,可以将A4-A7精简为一句代码:

A4=A1.select(empirica_score>=A3(1) && mfin_score>=B3(1)).group(

A3.pselect(empirica_score<~[1]):row,

B3.pselect(mfin_score<~[1]):col;

(accounts=~,A2.count(accounts.(account_no).pselect(~==custno)) /

B2.count(accounts.(account_no).pselect(~==customer_code))):rate

)

计算结果如下:

A9就是报表工具需要的数据集,接下来以JasperReport为例设计简单的交叉表,模板如下:

有三点需要注意:交叉表不能放在detail band中,Data
Pre Sorted属性需要设置为true,在报表中需要定义集算器对应的参数,比如pRowList,pColList。报表预览如下:

报表调用集算器的方法和调用存储过程一样,比如将本脚本保存为unregul.dfx,则在的JasperReport的SQL设计器中可以用unregul
$P{pRowList},$P{pColList}来调用。具体集成方案请参考相关文档。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-08 15:53:11

双区间交叉报表的制作的相关文章

双区间交叉报表的实现办法(实例)

使用Jasper或BIRT等报表工具时,常会碰到一些非常规的统计,用报表工具本身或SQL都难以处理,比如交叉表的行组和列组都是分段区间,测度(measurem)来自其他数据库表.集算器具有结构化强计算引擎,集成简单,可以协助报表工具方便地实现此类需求.下面通过一个例子来说明双区间交叉表的实现过程. 表account_detail的主键为account_no,与表Paysoft_result和NAEDO都是1对多关系.Paysoft_result的外键是custno,NAEDO的外键是custom

灵活数据源的固定行列交叉报表的制作

论坛里,http://bbs.csdn.net/topics/390883416中提的问题,其目的是为了实现一个固定行列的交叉表,用SQL准备好固定行数的数据源非常麻烦.而润乾集算报表则有非常灵活的计算能力,能够充分利用问题特点应付各种非常规的计算需求. 这里就以链接中业务为背景,给出集算报表实现某种固定列交叉报表的方案. 报表背景         源数据例如以下: 现须要在报表中显演示样例如以下内容: 这里要求依照分类统计总记录数.并将每月的记录数分别填充到1-12月中.当中无数据的记录显示为

VB.Net之旅—报表的制作(RDLC)

我们在这里以机房收费系统周结账单为例,讲解一下VS2008报表的制作 新建一个窗体,从工具箱中拖一个MicrosoftReportViewer控件到窗体中,点击MicrosoftReportViewer右边的小三角,然后选择设计新报表 选择已有数据源或添加新数据源 我们在这里添加数据源 选择已有连接或新建连接 我们在这里新建连接,测试连接成功后,选择确定 之后单击下一步,选择数据库对象,单击完成 选择新添加的数据源,选择下一步 选种左边字段,点击详细信息,点击下一步 点击下一步,对报表重命名,点

什么是交叉报表

交叉报表,也是报表当中常见的类型,和分组报表一样,也是基本的报表类型.分组报表是只有行方向上有分组,而交叉报表则是行.列方向都有分组的报表.传统的报表一般都是通过专门的交叉报表生成向导来设计交叉报表.      交叉报表看似简单,但是在实际应用中,特别是处理中国式复杂报表时,作用巨大:主要是因为中国式报表的自身特点决定的. 避开纯技术的数据源和运算等等不说,单单说一说中国报表的形式.中国式报表一般都会有格线,这样会使得报表内容一目了然.在格线划分的时候,交叉形式的格线使用率就很高.这样也就解释了

ActiveReports 报表应用教程 (7)---交叉报表及数据透视图实现方案

原文:ActiveReports 报表应用教程 (7)---交叉报表及数据透视图实现方案 在 ActiveReports 中可以通过矩阵控件非常方便的实现交叉报表,同时还可以设置数据的分组.排序.过滤.小计.合计等操作,可以满足您报表的智能数据分析等需求.在矩阵控件中组的行数和列数由每个行分组和列分组中的唯一值的个数确定.同时,您可以按行组和列组中的多个字段或表达式对数据进行分组.在运行时,当组合报表数据和数据区域时,随着为列组添加列和为行组添加行,矩阵将在页面上水平和垂直增长. 在矩阵控件中,

交叉报表列头排序时遇到的oracle问题—oracle ORA-12704:字符集不匹配、varchar2转化为nvarchar2字符缺失、case when else后的字符类型要一致

在做交叉报表列头的排序时,遇到这三个问题,下面具体来说一下. 设计的数据库的表结构如图1所示: 图1 要处出来student_name_,s.grade_,s.subject_name_,这三个属性,当时我是这样写的sql语句: select  s.student_name_, s.grade_,  s.subject_name_, case  s.subject_name_ when  '语文' then 'A语文' when  '数学' then 'B数学' when  '英语' then 

锐浪 报表, 交叉报表中 对交叉字段,做条件改变背景颜色 .

var fieldCount = Report.RunningDetailGrid.ColumnContent.ContentCells.Count; // 总字段列数 var lockFieldCount = Report.DetailGrid.CrossTab.ListCols; // 锁定字段列数 var crossFieldCount = fieldCount - lockFieldCount; for(var colIndex = 1; colIndex <=crossFieldCou

锐浪 报表, 当多行交叉报表时,对多行交叉报表中自由格中的多个字段控件,进行颜色控制. 取值 判断等实现

需要注意的点是: 1 . 要对自由格中对应的 字段框的背景填充方式改为:填充,否则没有效果. 2 . 代码中红色部门代码: Column 为明细网络对象属性中的 列集合 中的 交叉列的 名称,  Report.RunningDetailGrid.Columns.Item("Column_2") 3.  蓝色部门 为自由格中 控件的索引位置 ,也可以根据字段框的名称来进行控制如:  contentCell.Controls.Item("FieldBox8") 代码如下

动态格报表的制作

接触过很多客户,在没有数据系统以前,很多报表都是用 excel 画的.这些 excel 表,大部分都是业务人员为了方便记录数据直接画的,在这样画出来的表样中,分组合并单元格相当自由不受约束.而当业务人员把这些 excel 交给程序猿哥哥用报表工具制作时候,很自然地也会希望报表能像 excel 一样随心所欲的去合并单元格.但是,这就令程序猿哥哥苦恼了,因为通常使用的报表开发工具制作出来的分组报表都是中规中矩的,很难根据业务人员提供的样板随心所欲地合并单元格.但这样又会让业务人员感觉很死板,不够灵活