2013-04-09 17 views
1

我已经在本网站上使用了一段时间的信息,现在有一个大型项目需要您的一些专业知识。我在Oracle 11g环境中工作,并且还具有Cognos Report Studio 10.1使用Oracle和Report Studio构建数据分析报告

我正在构建一个多标签报表,显示部门出库单的分析。我创建了一个包含大约30列数据的自定义表格。从这里开始,每天必须在桌上进行超过150次计算。这些计算的一个例子是
1)今天收到多少订单?
2)今天收到的订单中,同一天发货多少?
3)有多少订单被搁置?

核心表上的4-5行查询基本上是100。我曾想过创建第二个表并使用WITH子句,在过程中执行计算并将其插入表中。

为了解决这个问题,有谁写过一个执行大量计算的程序/包,并且有任何可以建议的链接/网页?我的搜索并没有引导我创建这种性质报告的任何实例,并且希望确保我的方法尽可能高效。提前感谢任何信息/资源。

+0

的频率有多这些值的变化?你的报告中的数据最近有多久?如果可以接受的话,预先计算数据是相当标准的。 – 2013-04-12 09:04:14

+0

这些数据计算表示生产当天的交易和订单变化,它将保存一个月的数据。因此,除了当前日子以外,每天都需要填写过去的数据。 – RNORRIS 2013-04-12 11:25:34

回答

1

表和存储过程是一个好主意。一些注意事项: 你会每天归档这些事实吗?

即,您希望能够查找5天前暂停的订单,还是仅查看与当前日期相关的150个问题中的所有数据?

你可以有一个150列的表,每个问题一个表。如果您要存档数据并且每天需要一条记录,则这可能很有意义。

另一种方法是创建一个订单事实表只有两个或三个字段:

Fact_Name  VARCHAR2(30) 
Order_Fact  NUMBER(10,2) 
Last_Update_Date DATE 

你的Oracle存储过程将查询和更新一次的事实之一:

insert into ORDER_FACTS 
select "ORDERS_RECEIVED" fact_name, count(*) order_fact, sysdate 
from ORDER_TABLE 
where rcv_date = trunc(sysdate); 

commit; 

如果你只想保持一个记录每个事实,你会做一个更新。

如果您的某些问题的答案不是数字,您可能需要为VARCHAR2类型的事实保留一个单独的表。

如果你喜欢这个解决方案的声音,我可以明天设置一个示例程序。

编辑:

既然你存储的数据价值的30天内,我将创建的日期详细程度表,并有1列来存储每个结果。对于我的例子,我只包含3列,这样你就可以得到这个想法。首先,创建表来保存您的订单事实。

create table order_facts 
(DT    DATE, 
    ORD_RCV   NUMBER, 
    SAME_DAY_SHIPPED NUMBER, 
    ON_HOLD   NUMBER); 

我建议DT字段只存储日期。这将使表格更容易与日历表连接,如果日历表基于具有星形模式中的日历的表格,则可以轻松地将这些事实连接到其他报表。

接下来,创建过程来更新他们:

CREATE OR REPLACE PROCEDURE CALC_ORDER_FACTS (iDate date := trunc(sysdate), iPurgeDays number := 0) 
IS 
    ddate DATE; 
    dummy DATE; 
/* 
     Calc_order_facts 
     Date   Author Note 
     04/11/2013 XXX  Created this procedure 

    Param iDate (optional, default trunc(sysdate) 
    Specify Date to calculate order facts for 

    Param iPurgeDays number (optional, default 0) 
    Specify how many days to retain data. Data older than iPurgeDays will be deleted. 
    If 0, purging is disabled. 

*/ 

BEGIN 
    ddate := iDate; 

    IF iPurgeDays > 0 THEN 
     dbms_output.put_line('Purging data more than ' || to_char(iPurgeDays) || ' days old.'); 
     begin 
      delete ORDER_FACTS 
      where DT < trunc(ddate-iPurgeDays); 
      commit; 
     EXCEPTION 
     WHEN NO_DATA_FOUND THEN 
      dbms_output.put_line('Purge found no data.'); 
     WHEN OTHERS THEN 
      -- Consider logging the error and then re-raise 
      dbms_output.put_line('Purged failed, rollling back...');    
      rollback; 
     END; 
    END IF; 

    -- If date does not already exist in table, insert it 
    begin 
     select dt 
     into dummy 
     from order_facts 
     where dt = ddate; 
    EXCEPTION 
    WHEN NO_DATA_FOUND THEN 
     insert into order_facts 
     values (ddate, null, null, null); 
     commit; 
    END; 

    -- ORD_RCV 
    -- Calculate Orders received 
    update order_facts 
    set ord_rcv = 
     (select count(*) ord_rcv 
     from ORDER_TABLE 
     where rcv_date = ddate) 
    where dt = ddate; 
    commit; 

    -- SAME_DAY_SHIPPED 
    -- Calculate Orders received and shipped on ddate 
    update order_facts 
    set same_day_shipped = 
      (select count(*) same_day_shipped 
      from order_table 
      where rcv_dt = ddate 
      and ship_dt = ddate) 
    where dt = ddate; 
    commit; 

    -- ON_HOLD 
    -- Total orders on_hold 
    -- This method applies if you are only concerned with total on hold 
    update order_facts 
    set on_hold = 
      (select count(*) ON_HOLD 
      from order_table 
      where status = 'HOLD') 
    where dt = ddate; 
    commit; 

END CALC_ORDER_FACTS; 
+0

感谢您的回复,我将不得不进行30天的计算,因此计划将在第1天执行计算,并在执行时将等于SYSDATE的列添加到时间戳。这将允许我在第2天进行计算,并在交叉表查询中显示两天。 – RNORRIS 2013-04-10 12:06:02

+0

只是为了阐明,报告是交叉表查询的集合,其中水平值是执行计算的日期。所有计算都与跟踪业务单位绩效的日期相关。此报告一次将显示30天的数据。 – RNORRIS 2013-04-10 12:20:05

+0

答案中增加了步骤。 – Damienknight 2013-04-11 20:20:13

相关问题