Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle 历史记录、缺失记录、填空_Oracle_Plsql - Fatal编程技术网

Oracle 历史记录、缺失记录、填空

Oracle 历史记录、缺失记录、填空,oracle,plsql,Oracle,Plsql,我有一个表,其中包含按位置列出的成本历史记录。这些文件每月更新一次。 比如说 Location1, $500, 01-JAN-2009 Location1, $650, 01-FEB-2009 Location1, $2000, 01-APR-2009 如果我查询3月1日,我想返回2月1日的值,因为3月1日不存在。 我已经使用oracle分析工具编写了一个查询,但是这需要太多的时间。对于报表来说,这是很好的,但是我们使用它可以让用户通过前端和切换日期直观地查看数据,重新查询需要太长的时间,因为

我有一个表,其中包含按位置列出的成本历史记录。这些文件每月更新一次。 比如说

Location1, $500, 01-JAN-2009
Location1, $650, 01-FEB-2009
Location1, $2000, 01-APR-2009
如果我查询3月1日,我想返回2月1日的值,因为3月1日不存在。 我已经使用oracle分析工具编写了一个查询,但是这需要太多的时间。对于报表来说,这是很好的,但是我们使用它可以让用户通过前端和切换日期直观地查看数据,重新查询需要太长的时间,因为表大约有100万行。 因此,我的下一个想法是简单地用丢失的数据更新表。在上面的例子中,我只需添加一个与2009年2月1日相同的记录,只是将日期设置为2009年3月1日

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

更多信息:

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
)
然后我使用系统的查询将传入日期和时间。该表大约有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;

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

我已经填充了缺失的数据,还填充了虚拟数据,这样就不需要外部连接,从而多次提高了查询性能。它不干净也不完美,但我遵循莱夫拉的1定律,总是遵循有效的


您可以在Oracle中创建一个作业,该作业将在非高峰时间自动运行,以填充丢失的数据。看看:

实现这一点的最佳方法是创建一个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;

这个请求背后的确切用例是什么

在我工作过的每一个系统中,如果有三月的记录,而没有三月的记录,用户就会想知道这个事实。除此之外,他们可能还想调查3月份记录缺失的原因

现在,如果这基本上是一个性能问题,那么您应该调整查询。或者,如果它是一个表示问题—您希望生成一个包含12行的矩阵,而如果a由于某种原因没有记录,那么这是一个困难的问题—那么这是另一个问题,有各种可能的解决方案

但说真的,我认为数据库为丢失的记录发明替代品是一种糟糕的做法

编辑


我从你最近对你的问题的评论中看到,这确实是一个性能问题——索引解决了这个问题。因此,我觉得自己是正确的。

我同意-除非您确定填写缺失数据是正确的,否则可能不应该这样做。此数据是由另一个应用程序生成的,实际上并不用于此用途。有“丢失”的记录是很合理的,只是对于这个新的用途有问题。顺便说一句,我修复了我的索引,现在它运行得非常快。当然,他们现在正在改变要求,所以。。。