历史记录,缺少记录,填补空白

时间:2009-12-02 16:03:53

标签: oracle plsql

我有一张表格,其中包含按地点划分的费用历史记录。这些都是按月更新的。 例如

Location1, $500, 01-JAN-2009
Location1, $650, 01-FEB-2009
Location1, $2000, 01-APR-2009

如果我查询3月1日,我想返回2月1日的值,因为3月1日不存在。 我使用oracle分析编写了一个查询,但这需要花费太多时间(对于报表来说会很好,但是我们使用它来允许用户通过前端和切换日期直观地查看数据,重新查询太长,因为表是100万行)。 所以,我的下一个想法是简单地用缺少的数据更新表。在上面的例子中,我只是添加一个与01-FEB-2009相同的记录,除了将日期设置为01-MAR-2009。

我想知道你们是否都对如何做到这一点有所了解。 我的计划是简单地为一个位置创建一个游标,获取第一个记录,然后获取下一个记录,如果下一个记录不是下个月,则插入缺失月份的记录。

更多信息:

CREATE TABLE MAXIMO.FCIHIST_BY_MONTH
(
  LOCATION     VARCHAR2(8 BYTE),
  PARKALPHA    VARCHAR2(4 BYTE),
  LO2          VARCHAR2(6 BYTE),
  FLO3         VARCHAR2(1 BYTE),
  REGION       VARCHAR2(4 BYTE),
  AVG_DEFCOST  NUMBER,
  AVG_CRV      NUMBER,
  FCIDATE      DATE
)

然后我正在使用的查询(系统将传递日期和parkalpha)。该表大约有100万行,而且,虽然报告需要一段合理的时间,但交互式显示需要太长时间

select location, avg_defcost, avg_crv, fcimonth, fciyear,fcidate from
(select location, avg_defcost, avg_crv, fcimonth, fciyear, fcidate,
max(fcidate) over (partition by location) my_max_date 
from FCIHIST_BY_MONTH 
where fcidate <='01-DEC-2008'
and parkalpha='SAAN'
)
where fcidate=my_max_date;

3 个答案:

答案 0 :(得分:0)

填写缺失的数据将(如果您小心)使查询更简单,运行更快。 我还要在表格中添加一个标志,表示数据缺少填写的数据,以便if 您需要稍后删除它(或创建没有它的视图)。

我填写了缺失数据并填写了虚拟数据,因此不需要外连接,以便多次提高查询性能。它不是“干净”和“完美”,但我遵循Leflar的#1法则,“总是适用于有效的方法。”

您可以在Oracle中创建一个作业,该作业将在非高峰时间自动运行以填充缺失的数据。看看:This question on stackoverflow about creating jobs.

答案 1 :(得分:0)

执行此操作的最佳方法是创建一个从当前向后工作的PL / SQL存储过程,并运行无法返回数据的查询。它每月都无法返回数据,因此会为缺失的数据插入一行。

create or replace PROCEDURE fill_in_missing_data IS
  cursor have_data_on_date is
    select locaiton, trunc(date_filed) have_date
    from the_table
    group by location, trunc(date_field)
    order by desc 1
  ;  
  a_date date;
  day_offset number;
  n_days_to_insert number;
BEGIN
   a_date := trunc(sysdate);
   for r1 in fill_in_missing_data loop
     if r1.have_date < a_date then
       -- insert dates in a loop
       n_days_to_insert := a_date - r1.have_date; -- Might be off by 1, need to test.
       for day_offset in 1 .. n_days_to_insert loop
         -- insert missing day
         insert into the_table ( location, the_date, amount ) 
            values ( r1.location, a_date-day_offset, 0 );
       end loop;
     end if; 
     a_date := r1.have_date;
     -- this is a little tricky - I am going to test this and update it in a few minutes
   end loop;
END;

答案 2 :(得分:0)

此请求的确切用例是什么?

在我参与的每个系统中,如果有一个MARCH记录并且没有MARCH记录,用户想知道这个事实。除了他们可能想要调查为什么缺少MARCH记录。

现在,如果这基本上是一个性能问题,那么你应该调整查询。或者如果它是表示问题 - 你想要生成一个十二行的矩阵,如果由于某种原因没有记录就很难 - 那么这是一个不同的问题,有各种可能的解决方案。

但严重的是,我认为数据库发明缺失记录的替代品是一种不好的做法。

修改

我从您最近对您的问题的评论中看到,结果确实是性能问题 - 索引修复了问题。所以我觉得自己是正确的。