首先看一下下面这个表?q个表样是润乄一个示例表?接着介绍birt 是如何做?/p>
q个表样是报表中最常见的一U需求了Q把不同_度的数据聚合到同一_度?
我们用automobile 表示汽R? 用houseproperty 表示房? 用estate表示土地?用others 表示其他?他们都有customerid 来表C客户名U?customers 表有customerid 和customername
1. 用视图来拼数?/p>
对于 automobile 聚合使用一个autoview , sql 如下
select sum(automobile price* quantity) autototal, customerid from automobile group by customerid
对于 houseproperty 使用如下view
select sum( house price * quantity ) housetotal, customerid from houseproperty group by customerid
对于 土地和其他也是差不多cd的sql
得到了上面这四个视图之后, 把customers 表根据customerid 和其他四个视图join h.
select customername , autototal , housetotal , estatetotal , othertotal
from customers c , automobile a , houseproperty h , estate e , others o
where 四个视图和customers的连接条?/p>
׃q个表样q不涉及C 汽RQ房产,土地Q?其他表中的Q何一个客户ؓ? 所以暂时也不考虑左右q接的问?
2. 使用Birt 的Joined Data Set
Birt 提供的Joined Data Set 跟数据库里面的视图是差不多的概念Q不过一个是在数据库内部join 数据Q一个是使用Java 循环的方式join 数据.
跟上面创图一P创徏四个DataSet , 输出两个字段: customerid ?total.
然后创徏一个Joint Data Set , 把customers 表和 autototal DataSet 按照customerid joinh.q时得到四个字段 customers.customername , customers.customerid , auto DataSet.customerid Qauto DataSet.autotal . 最后我们把q个Joint DataSet 命名为jdataSet1 (代表的是autoDataSet ?customers 产生的Joint DataSet ).
然后l箋创徏另一个Joint Data Set 把customers 的customerid 和前一步创建的jDataSet1 按照customerid join h得到一个第二个Joint DataSet1 ,我们命名为jDataSet2 .
以此cLQ最后我们输?个字D? customers.name , auto.total , house.total , estate.total , others.total , 实际输出可能在customers.customerid 上重复了4?
上面两种方式报表的做法主要有两点差别:
1. 性能
如果本n数据库单独执行一个视囄sql l果比较,而本w的automobile 表数据量比较大(也就是说一个customer寚w常多的automobile 记录) , 那么使用数据库视囑ְ会比较慢. 因ؓ数据库在试得到4个视囄l果q行了一些不必要的按照automobiel表的customerid和customers的customeridq? 行的比较操作( 如果有烦引肯定是对烦引进行了多次不必要的? ,q时候用Java的这U@环方式会比较快一?. 如果本nl构集比较大Q那么还是用数据库本w的排序和join 比较? q个道理比较cM于数据库中如果结构集大于5% ׃要走索引,直接q行全表扫描.只不q这是一个java 版的.
2. 左右q接的问?/p>
如果q个表的数据不是以customers里面的数据ؓ主,而是以四个视囑օ中的一个ؓ?q时候要情况可能会比较复杂一?׃我不太清楚birt 里面joint data set 计算的方式是怎样的,所以也不太好评?不过如果不用joint data set , 是使用一般的~程的方?那么按照下面q个思\会比较好:
a , b , c , d ,e 为customers , automobiles view (后面写avlist 表示q个?, housetotal view , 里面的指? 四个view 都已l排好了?group by 是默认排序的. outlist 表示最后需要的输出 , row表示最后输出的一条数?/p>
for ( 按照L据@? {
row.customerid = customers.customerid;
if( customers.customerid == avlist[b].customerid) {
outlist[x].autotaol = avlist[b].autotal ;
b++
}
四个view 同一个判断方? 但是每个view 的指针指的是不一L.
最? outlistSet . add (outlist[x])
}
如果数据源本w的数据量也很大Q需要输出的数据也很多,则上面两U方式都会有性能问题Q这时可以考虑商业里面的万金a方式: ETL
3. ETL
从上面这个表L来,可能会有两个隐含条g.一个是聚合的数据粒度在旉上是月,另一个在销售地点粒度上是:支行086001-301 , 所以用ETL一开始就聚合数据可能会更好的解决性能问题.另外一个是如果用户惌排序和过滤数据的话用一个单独的ETL聚合表也比拼数据的方式好的多.
q篇文章的目的ƈ不只是想解释一个做表的问题Q而是说明商业的一些问题不光需要站在一个独立的角度思考,有些问题本n可能随着环境的一些变化? 采取对应的措施,比如上面Z解决排序Q过滤,左右q接Q性能问题都需要从不同的角度来考虑问题.有时候可能一个做表的问题不光只是要限定在sql 或某个报表Y件的本nQ有时候某个ETL问题可能不关只是ETLp解决?随着情况的复杂可能需要从整个商业的全局来进行考虑Q商业智能越来越們 与多个解x法的融合.
本文原文?http://www.gemini5201314.net
如果你对ETL中性能优化问题有兴的话,也可以查看另一关于在ETL中性能优化要站在全局的角度,而不是只在数据库角度的文?