首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > 数据库开发 >

怎么在BO的报表中过滤数据

2012-12-16 
如何在BO的报表中过滤数据我在做报表的过程中,遇见一个问题。客户要求在浏览报表的时候,要求进行公司结构的

如何在BO的报表中过滤数据
我在做报表的过程中,遇见一个问题。
客户要求在浏览报表的时候,要求进行公司结构的数据过滤。
详细的说,就是集团A底下有公司A,公司B,公司C
在浏览报表的时候,集团A可以浏览全部的数据,各公司间只能看自己的相关数据
并且,在这个基础上,还有公司部门的结构。
比如,各个公司可能有自己的财务部门,人事部门等
集团A的财务,可以看所有的财务报表,就是说能看集团A+3个公司的财务报表,不能看人事的。
同样,集团A的人事也只能看所有的人事报表。
但是到了下面公司,各公司只能看本公司的相关报表。
比如,公司A的财务部门只能看本公司的财务,不能看其他公司的财务,也不能看本公司的人事。
而同时,财务报表可能含员工薪资,福利,资产等几个块的报表;
人事可能含人员花名册,人员培训情况等几个块的报表。

以上是大的结构上的需求。

小需求是,客户要求把BO报表集成到门户里。
先选择公司,再选择部门,最后选择报表。
比如,公司A的财务领导先选择公司A,然后选择财务,最后选择财务里的员工薪资报表。
要求,当用户跨权限浏览的时候,提示报错。报错后的处理,只要不给他看跨权限的数据,怎么处理都行,比如直接返回上一页,或者跳到出错页。
PS:各公司的一把手,有权利浏览本公司所有部门的所有报表

请问大家有什么好的设计方法



[最优解释]


没什么好办法,因为从数据上讲,universe是最小的授权单位。
一般的做法,有时是只授给用户report的权限,这样这个用户就只能刷新和查看这个预先设计好的report

或者建不同的universeA,universeB,universeC每个中只desinger中把filter的where 子句加上。

以前做过一个,是通过在数据库中设计不同的视图,把视图的权限授给不同的用户。比如在oracle中,建usera,userb,userc
在usera schema中建成 usera.view_data as select * from data where companyid='A',相应B,C中也一样。

然后你可以设置connection让用户登录的时候输入oracle的账号。
[其他解释]
又错了
。。。。


select 
decode('时间参数','',1,'时间字段') as 时间, 
decode('地区参数','',1,'地区字段') as 地区, 
decode('部门参数','',1,'时间字段') as 部门, 
sum(度量) as 度量 
from 表 
where 
... 其他条件 
....

[其他解释]
自己顶自己
[其他解释]
第一种方法是可行的,但是会随着公司结构的膨胀而集聚膨胀
并且,目前的公司结构就很庞大了
第二种方法能说详细下吗?
因为用户登陆的是BO的系统,帐号都是BO里,好象跟数据库关系不大

[其他解释]


在你设置universe 的connection的时候,有一个选项就是可以让用户自己输入数据库的账号。

这样如果你能集成BO,WINDOWS,ORACLE/SQL SERVER的账号,比如全部都使用windows的账号进行验证。则可以方便的使用第三种。

第二种很简单。建三个universe, 记得是在class上还是在表上可以设置条件
[其他解释]
在数据库层面一般是通过给用户授权来解决的。
[其他解释]


BO 不是数据库,是数据仓库分析工具。有自己的分组授权对象和结构。一般是通过在BO中直接进行授权。只有楼主这种特殊需要才需要考虑不同的方案来实现。
[其他解释]
可以在一张报表中,查询两个UNIVERSE吗?
我是说,把UNIVERSE像表一样联结查询,然后把结果反映到一个报表上

[其他解释]


在一个REP报表文件中可以插入多个universe. 菜单,插入,表格,然后你选择 from different way就行了。

不同的universe没办法直接UNION,你需要先建一个filed link,然后只能做join,但由于companyid上不重复,一个是A,一个是B,所以join后会显示成两列,看看能不能通过公式把这两列合并起来。
[其他解释]
啊~~烦啊
让我再考虑考虑
我觉得这个问题是比较普遍的问题,希望能搞出个最佳解决方案
[其他解释]


如果数据库是SQL SERVER则建议用第三种方法。直接在数据侧把用户的widnows 账号加到sql server 的用户组中即可。这样就用一个universe实现了。
[其他解释]
哎……关键时候哪壶不开提哪壶啊
我们用的是ORACLE
[其他解释]


呵呵,我们也是oracle,所以用了方案二,5个universe ,4个是各分公司的,一个是可以看所有的
[其他解释]
来抢沙发了啊~~~~~~~~~~~~~
------其他解决方案--------------------


看来这种需求真的是很普遍。

最开始我们用BV做报表数据源的,结果就是因为这个不同层级的问题,改用了unv。
对于不同层级的人,BO的技术人员建议我们用filter,但是加filter是个痛苦的事情,我们用sdk接口去加
因为用户比较多,有的一个报表的filter要加到上千个,当一个报表的filter超过200个的时候,再加一个要3秒以上,越多越慢,后来到了10秒以上
到最后基本不可忍受。
后来我们就摒弃了这个方案,用参数+SQL来实现。


数据库是oracle.
我们是用水晶报表做rpt来连unv的

比如我们要区分总公司和分公司,unv的语法是这样的,当然实际情况比这个复杂的多
Select * from tbl where decode('参数','',1,{分公司字段})=decode('参数','',1,'参数')
参数应该是个prompt语法,我就不写了

如果输入参数为空(当然,也可以是个特殊值,比如000等),那么
decode('参数','',1,{分公司字段})=decode('参数','',1,'参数')
=>
1=1
显示数据全集

否则
{分公司字段}='参数'
仅显示输入参数,如本公司的数据

于是关键就落在前段上如何控制不同的用户必须输入自己所在级别的,现在我们是自己编程来控制这一端的
数据库里面建了一套人员层级表(对应BOE账号表,就是每个账号对应不同的人,以及他的层级信息,及权限级别等),
登陆时首先登陆到BOE中,登陆成功后从我们自己的库里取层级
然后根据报表参数,前端界面显示一个层级列表

分公司 下拉菜单
部门   下拉菜单

总公司的能看到所有的分公司和部门,某公司的只能看自己公司和部门,某部门的就只能看自己的部门
这样保证前台传进去的参数是有效的,当然,为了安全,用户提交后,需要绕到层级表里去检查权限的
获得这个参数后,通过opendoc把参数传给报表来呈现。

表述的不是很清楚好像~~

另外BOE的报表权限也比较抽象,虽然有SDK,但是也有些麻烦。
现在我们正在准备把这一层也接管过来。

纯用BO套件,有时候处理起来确实有点力不从心。
[其他解释]
补一下,所有的分公司数据,在一个unv中实现的。
[其他解释]

引用:
看来这种需求真的是很普遍。 

最开始我们用BV做报表数据源的,结果就是因为这个不同层级的问题,改用了unv。 
对于不同层级的人,BO的技术人员建议我们用filter,但是加filter是个痛苦的事情,我们用sdk接口去加 
因为用户比较多,有的一个报表的filter要加到上千个,当一个报表的filter超过200个的时候,再加一个要3秒以上,越多越慢,后来到了10秒以上 
到最后基本不可忍受。 
后来我们就摒弃了这个方案,用参数+SQL来实现。 

那你们的universe是以什么为单位的?或者说细化到什么程度?
因为据我所知,openDocument的参数列表里只能选择报表,不能从已有的报表中筛选数据
[其他解释]
不必再单独开发给用户进行二次报表开发

开发
==>
开放
[其他解释]
universe 细化到所需最细的粒度(如果这个数据要下到部门,那么就细化到部门),也就是容纳所有数据
但是unv上本身不分配权限
(可能我们的应用场景比较简单,因为报表是直接由我们开发的,不必再单独开发给用户进行二次报表开发)

openDocument可以传参数(就是一系列以lsS开头的那种,文档里有说明的),unv中根据参数来过滤数据。

就是这个效果

Select * from tbl where 
decode('参数1','',1,{分公司字段})=decode('参数1','',1,'参数1') 
and
decode('参数2','',1,{部门字段})=decode('参数2','',1,'参数2') 



[其他解释]
这个最细,也是经过汇总压缩的,不可能直接在原子层取数
我们现在有4T数据,4个层级20000个组织结构的样子,目前的方案基本可涵盖过来
性能还可以
[其他解释]
其实我一直不想用最细化粒度做报表的
因为我们现在的做的客户架构很大
并且,这个方法治标不治本
不是最佳解决方案
[其他解释]
压缩(这里是指数据的汇总)就是把明细数据,汇总到具体的维度和指标。
也就是基本的
create table rpt_tbl_001
as 
select f1,f2,f3 sum(f4) f4,sum(f5) f5
from tbldetail

比如说保险行业的,保单信息。我们要统计周期内按险种分类的承保理赔信息。
那么从原始的明细表,汇总出来的数据是这样的

日期 险种 分公司 部门 承保数量 承保金额 理赔数量 理赔金额

当然,就上面这个例子来说,这个表的数据,可能是来自于多个原子表的
如保单信息表,承保信息表,理赔信息等  ,实际上表更多。

如果单纯是原子表,每个表内的数据一般都是千万条的,经过上述汇总后,出来的数据,可能是万条级别的。、
而且不用再进行表间关联。结合分区索引,效率上基本上不会有问题。

现在我们在原始数据与报表间有一个报表数据层。这一般也是通用做法。
把原子层数据根据业务逻辑及报表需要,抽取成报表层的汇总数据。
将尽可能少的数据传递给报表。
报表上不涉及具体的业务逻辑,只负责展现逻辑。

[其他解释]
引用:
这个最细,也是经过汇总压缩的,不可能直接在原子层取数 
我们现在有4T数据,4个层级20000个组织结构的样子,目前的方案基本可涵盖过来 
性能还可以

压缩是什么意思?
怎么个压缩法?


[其他解释]

引用:
压缩(这里是指数据的汇总)就是把明细数据,汇总到具体的维度和指标。 
也就是基本的 
create table rpt_tbl_001 
as 
select f1,f2,f3 sum(f4) f4,sum(f5) f5 
from tbldetail 

比如说保险行业的,保单信息。我们要统计周期内按险种分类的承保理赔信息。 
那么从原始的明细表,汇总出来的数据是这样的 

日期 险种 分公司 部门 承保数量 承保金额 理赔数量 理赔金额 

当然,就上面这个例子来说,这个表的数据,可能是来自于多…

你说的这个我明白了
我现在关心openDocument的数据过滤能做到什么程度?
比如我现在的一个维度有5个粒度,我能直接筛到粒度3以下的数据吗?
还有就是,粒度3以上的数据,用户能不能看到?如果遇见交叉维怎么办?
[其他解释]
不好意思,写错了。
应该是类似这样

create table rpt_tbl_001 
as 
select f1,f2,f3 sum(f4) f4,sum(f5) f5 
from tbldetail 
group by f1,f2,f3
[其他解释]
引用:
我在这方面概念性术语比较薄弱,呵呵。比如说交叉维,我们可能用到了,但是可能没用到这个术语。 

openDocument 只是负责传参数,具体的过滤效果,还是看你unv的设计。 
只要能在sql里实现出来,那么unv里应该就能表达出来(派生表) 

我更菜,我先学了不到2个月的BI开发……
所谓的交叉维就是多个维度确定一个度量
就好象三维空间的坐标一样
[其他解释]
我在这方面概念性术语比较薄弱,呵呵。比如说交叉维,我们可能用到了,但是可能没用到这个术语。

openDocument 只是负责传参数,具体的过滤效果,还是看你unv的设计。
只要能在sql里实现出来,那么unv里应该就能表达出来(派生表)


[其他解释]
比如说,销售表
维度可能有时间,地区,部门
度量是金额
这样的话,要确定一个度量(如果是全维度的话)就需要3个维度
也就是3个维度确定一个度量

其实这个词是我自己搞的比较形象的一个词……
我也不知道到底专业术语里有没有……
[其他解释]
是不是这个意思呢?

2009年1月 苹果  销售量 为 1000元 这个玩意?

开始的时候,BO的人还讲星型模型,主题表,事实表之类的,呵呵
太复杂了,我们还是用了最一般的数据模型

[其他解释]
呵呵,这个其实没那么复杂,

维度可能有时间,地区,部门 
度量是金额 

在我们的中间表里是这样存储的

时间,地区,部门 ,度量

这样可以进行任意维度的组合汇总啊

select 时间,sum(度量)  from 表 group by 时间
select 时间,地区,sum(度量)  from 表 group by 时间,地区
select 时间,地区,部门,sum(度量)  from 表 group by 时间,地区,部门

现在的问题就是如何在一个unv里实现这个效果。

假设我们有三个参数:时间,地区,部门
参数为空就不参与维度
那么语句这样构造的

select
decode('时间参数','',1,'时间字段') as 时间,
decode('地区参数','',1,'地区字段') as 时间,
decode('部门参数','',1,'时间字段') as 时间,
sum(度量) as 度量
from 表
where
... 其他条件
 Group By
decode('时间参数','',1,时间字段), 
decode('地区参数','',1,地区字段),
decode('部门参数','',1,部门字段)


特别注意group by 后面的语法
decode('时间参数','',1,'时间参数'),
如果参数为空,则返回一个1,
也就是这个字段不需要进行group by


[其他解释]
实际上,感觉在数据方里是应该有这个说法的
[其他解释]
顶!非常有用的帖子,很多用户都有这样的要求。
[其他解释]
顶,很有用

热点排行