BIEE在直接查询3NF模型时,如果不注意很容易出现Fan traps,具体如下所示:
order_header是订单头,上面有该订单的运费(运费针对整个订单收取,而非订单中的具体商品)
order_lines是订单明细,上同有单项商品的金额
times和order_heade的关系是1:N
order_header和order_lines的关系是1:N
这个时候我们应该怎样构建逻辑模型呢?有人会说了,我们这样就可以
把ORDER_FACT的逻辑表源ORDRE_HEADER映射到ORDER_HEADER和ORDER_LINES两张表上,然后新建AMOUNT和TRANSFER_COST两个指标分别映射到
ORDER_LINES的AMOUNT 以及ORDER_HEADER的TRANSFER_COST字段上
OK,这样没有问题么?很明显这样肯定是有问题的 这样会造成订单的配送成本被多次重复计算!
因为生成的SQL如下:
select order_date,
sum(b.transfer_cost) transfer_cost,
sum(a.amount) amount
from order_lines a,
order_header b,
times c
where a.form_id=b.form_id
and c.time_id=b.order_date
group by order_date
结果为:
可以看到,TRANSFER_COST被重复计算了3次,正确的值应该为12。
那么我们应该怎么解决这个问题呢?很简单,使用多路SQL即可,也就是说用两条SQL来分别得以这两个指标值,如下:
SQL1:求运费
select order_date,
sum(b.transfer_cost) transfer_cost
from order_header b,
times c
where c.time_id=b.order_date
group by order_date
SQL2:求订单金额
select order_date,
sum(a.amount) amount
from order_lines a,
order_header b,
times c
where a.form_id=b.form_id
and c.time_id=b.order_date
group by order_date
最后在将两者拼起来即可!
怎么在BIEE中实现呢?
很简单,结合多逻辑表源和别名功能就好了。
方法如下:
1、对ORDER_HEADER新建一个别名,命名为ORDER_HEADER2,然后将其与TIMES表关联,如下图所示:
2、对逻辑表ORDER_FACT增加一个逻辑表源ORDER_HEADER2映射到ORDER_HEADER2物理表上,然后取消逻辑字段TRANSFER_COST现有的映射,
映射到新的逻辑表源ORDER_HEADER2上,如下图所示:
OK!
附测试脚本;
create table ORDER_HEADER
(
form_id INTEGER,
order_date DATE,
transfer_cost NUMBER
);
create table ORDER_LINES
(
form_id INTEGER,
product_code VARCHAR2(10),
amount NUMBER
);
create table TIMES
(time_id date);
insert into order_header values(1,to_date('1998-1-1','yyyy-mm-dd'),12);
insert into order_lines values(1,'AA',67);
insert into order_lines values(1,'BB',128);
insert into order_lines values(1,'CC',210);
insert into times(to_date('1998-1-1','yyyy-mm-dd'));