将每日快照转换为PostgreSQL中的范围

时间:2015-11-25 21:44:35

标签: postgresql data-warehouse

我有一张非常大的桌子,每年有多年的快照,显示每天的数据。为了便于说明,该表看起来像这样:

Part   Qty   Snapshot
----   ----  --------
 A       5   1/1/2015
 B      10   1/1/2015
 A       5   1/2/2015
 B      10   1/2/2015
 A       6   1/3/2015
 B      10   1/3/2015
 A       5   1/4/2015
 B      10   1/4/2015

我想实现一个缓慢变化的数据方法,并将这些数据折叠成一个看起来像这样的形式(假设当前日期是1/4/15)

Part   Qty   From      Thru      Active
----   ----  --------  --------  ------
 A       5   1/1/2015  1/2/2015  I
 B      10   1/1/2015  1/4/2015  A
 A       6   1/3/2015  1/3/2015  I
 A       5   1/4/2015  1/4/2015  A

我有一个每天运行的功能,因此当我捕获最新的快照时,我将其转换为此方法。一旦数据实际加载到具有活动标志“C”(当前)的表中,该函数将从巨型表(实际上在DB2中)中运行。

这对我来说是有用的(一旦我加载了所有过去的日期),但是我希望有一种方法可以一次性完成所有现有日期,并将各个快照日期转换为范围。 / p>

对于它的价值,我当前的方法是为每个可能的日期值运行此函数。虽然它正在工作,但它很慢,而且我有几年的历史可以处理,因为我一次循环一天。

表:

create table main.history (
  part varchar(25) not null,
  qty integer not null,
  from_date date not null,
  thru_date date not null,
  active_flag char(1)
);

create table stage.history as select * from main.history where false;

create table partitioned.history_active (
  constraint history_active_ck1 check (active_flag in ('A', 'C'))
) inherits (main.history);

create table partitioned.history_inactive (
  constraint history_active_ck1 check (active_flag = 'I')
) inherits (main.history);

处理一天新数据的功能:

CREATE OR REPLACE FUNCTION main.capture_history(new_date date)
  RETURNS null AS
$BODY$
DECLARE
  rowcount integer := 0;
BEGIN

  -- partitioned.history_active already has a current snapshot for new_date

  truncate table stage.history;

  insert into stage.history
  select
    part, qty,
    min (from_date), max (thru_date),
    case when max (thru_date) = new_date then 'A' else 'I' end
  FROM
    partitioned.history_active
  group by
    part_qty;

  truncate table partitioned.history_active;

  insert into partitioned.history_active
  select * from stage.history
  where active_flag = 'A';

  insert into partitioned.history_inactive
  select * from stage.history
  where active_flag = 'I';

END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

0 个答案:

没有答案