润乾报表解决大数据量树形结果数据方案
问题描述:
在武钢遇到树形数据问题,其数据结构模型可简单描述为ID,FARTHERID,NAME,测试数据如下图:
希望在报表中得到的展示效果为:
解决方法:
1)数据量较小的情况:
如果数据量比较小,可以在报表的层次上进行处理,如下图所示:
A2单元格表达式:=ds1.Group(ID,false,fartherid==0)
A2单元格显示值表达式:=ds1.select1(NAME,ID==VALUE())
B2单元格表达式:=ds1.Group(ID,false,fartherid==A2,,,,true)
B2单元格显示值表达式:ds1.select1(NAME,ID==VALUE(),TRUE)
C2单元格表达式:=ds1.Group(ID,false,fartherid==B2,,,,true)
C2单元格显示值表达式:ds1.select1(NAME,ID==VALUE(),TRUE)
需要注意的时,B2,C2单元格表达式都是从root数据集表达式提取数据。
B2,C2单元格也可以用query函数来替代group函数,效果是一样的。
2)数据量较大的情况
如果数据量比较大,当可能多达几十万条数据的时候,通过group函数或者query函数会很大的影响性能,因为每个单元格都要遍历几十万条数据,然后进行过滤。就武钢具体问题来说,报表展示需要几分钟,甚至会报内存溢出,所以这种情况下,最好在数据库sql的层次上做初步的处理。
此数据结构数据的sql:
with tree_select (id, level, country, province, city)
as
(
select id, 1 as level, name as country, cast(‘ ‘ as varchar(50)) as province, cast(‘ ‘ as varchar(50)) as city
from test_tree as tree1 where fartherid =0
union all
select tree2.id, 2 as level, select1.country as country, name as province, cast(‘ ‘ as varchar(50)) as city
from test_tree as tree2, tree_select as select1 where tree2.fartherid = select1.id and select1.level = 1
union all
select tree3.id, 3 as level, select2.country as country, select2.province as province, name as city
from test_tree as tree3, tree_select as select2 where tree3.fartherid = select2.id and select2.level = 2
)
select country, province, city from tree_select where level =3
注意:此sql采用递归的思路,使用的特定条件,一是知道fartherid,二是要知道有几层。
执行后的结果集:
润乾报表在此结果集的基础做分组报表,如下图:
A2单元格表达式:=ds1.Group(country,false)
B2单元格表达式:=ds1.Group(province,false)
C2单元格表达式:=ds1.Group(city,false)
此时计算展示数据,性能效率将有很大的提升。
为了进一步提升效率,可以创建一个中间表,在报表并发量,运算量少的时候定时执行上面sql,将查询得到的结果集保存到中间表,报表从中间表中提取数据,进行分组运算即可。
总结:
对于大数据量树形结构的数据,将所有运算都放到报表中执行,效率比较低,尽量将数据运算在数据库的层次上完成,报表只起到展示作用或者说尽量少一些业务运算,将大大提过报表的性能。