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由于某种原因没有记录,那么这是一个困难的问题—那么这是另一个问题,有各种可能的解决方案 但说真的,我认为数据库为丢失的记录发明替代品是一种糟糕的做法 编辑
我从你最近对你的问题的评论中看到,这确实是一个性能问题——索引解决了这个问题。因此,我觉得自己是正确的。我同意-除非您确定填写缺失数据是正确的,否则可能不应该这样做。此数据是由另一个应用程序生成的,实际上并不用于此用途。有“丢失”的记录是很合理的,只是对于这个新的用途有问题。顺便说一句,我修复了我的索引,现在它运行得非常快。当然,他们现在正在改变要求,所以。。。