Having read the books - I understand that a daily snapshot should - by definition - be taken every day. I am in the specialty credit card space. Ours is not a daily use card. Typically - our card is used only once or twice per month.
So I can't give it up. I don't want to insert 31 rows where only a small number of changes have occurred. I want to implement the snapshot as a view. I would insert into a FactChange table only when a change in balance is observed.
For the below example uses cross join, left outer join and lag to accomplish ALMOST exactly what I want - a 20 row result set addressing 2 accounts over 10 days. The lag gets the previous value and I can coalesce for the FIRST day of inactivity. It fails on the second, third, yada yada because the previous day as null.
What I need is lag(c.Balance, LastNonNull) That LastNonNull is the part I can't get my head around. Can anyone help??
-------------------------------
create table DimDate
(
DateKey int not null,
constraint PK_Date primary key clustered (DateKey)
);
go
insert into DimDate values
(20130601),
(20130602),
(20130603),
(20130604),
(20130605),
(20130606),
(20130607),
(20130608),
(20130609),
(20130610);
go
create table DimAccount
(
AccountKey int not null,
constraint PK_Account primary key clustered (AccountKey)
);
go
insert into DimAccount values
(1),
(2);
go
create table FactBalanceChange
(
DateKey int not null,
AccountKey int not null,
Balance money not null,
constraint PK_BalanceChange primary key clustered (DateKey, AccountKey),
constraint FK_BalanceChange_DateKey foreign key (DateKey) references DimDate(DateKey),
constraint FK_BalanceChange_AccountKey foreign key (AccountKey) references DimAccount(AccountKey)
);
go
insert into FactBalanceChange values
(20130601, 1, 10.00),
(20130601, 2, 10.00),
(20130604, 1, 5.00),
(20130607, 2, 5.00),
(20130609, 1, 4.00),
(20130609, 2, 4.00);
go
create view FactBalanceSnapshot as
select
d.DateKey,
a.AccountKey,
coalesce(c.Balance, lag(c.Balance, 1) over (partition by a.AccountKey order by d.DateKey)) as Balance
from
DimDate d
cross join
DimAccount a
left outer join
FactBalanceChange c
on d.DateKey = c.DateKey
and a.AccountKey = c.AccountKey;
go
select * from FactBalanceSnapshot;
So I can't give it up. I don't want to insert 31 rows where only a small number of changes have occurred. I want to implement the snapshot as a view. I would insert into a FactChange table only when a change in balance is observed.
For the below example uses cross join, left outer join and lag to accomplish ALMOST exactly what I want - a 20 row result set addressing 2 accounts over 10 days. The lag gets the previous value and I can coalesce for the FIRST day of inactivity. It fails on the second, third, yada yada because the previous day as null.
What I need is lag(c.Balance, LastNonNull) That LastNonNull is the part I can't get my head around. Can anyone help??
-------------------------------
create table DimDate
(
DateKey int not null,
constraint PK_Date primary key clustered (DateKey)
);
go
insert into DimDate values
(20130601),
(20130602),
(20130603),
(20130604),
(20130605),
(20130606),
(20130607),
(20130608),
(20130609),
(20130610);
go
create table DimAccount
(
AccountKey int not null,
constraint PK_Account primary key clustered (AccountKey)
);
go
insert into DimAccount values
(1),
(2);
go
create table FactBalanceChange
(
DateKey int not null,
AccountKey int not null,
Balance money not null,
constraint PK_BalanceChange primary key clustered (DateKey, AccountKey),
constraint FK_BalanceChange_DateKey foreign key (DateKey) references DimDate(DateKey),
constraint FK_BalanceChange_AccountKey foreign key (AccountKey) references DimAccount(AccountKey)
);
go
insert into FactBalanceChange values
(20130601, 1, 10.00),
(20130601, 2, 10.00),
(20130604, 1, 5.00),
(20130607, 2, 5.00),
(20130609, 1, 4.00),
(20130609, 2, 4.00);
go
create view FactBalanceSnapshot as
select
d.DateKey,
a.AccountKey,
coalesce(c.Balance, lag(c.Balance, 1) over (partition by a.AccountKey order by d.DateKey)) as Balance
from
DimDate d
cross join
DimAccount a
left outer join
FactBalanceChange c
on d.DateKey = c.DateKey
and a.AccountKey = c.AccountKey;
go
select * from FactBalanceSnapshot;
John