14. oktober 2009 - 22:01
Der er
3 kommentarer og
1 løsning
Rekursiv opdatering
Jeg har en simpel tabel
ID int
fk_user int
Dato DateTime
EventText varchar(50)
Beloeb varchar(50)
Saldo varchar(50)
Mit problem er, at der er gået kuk i posterne, således at Saldo ikke længere passer, normalt ser det sådan jer ud:
1 12 2009-10-13 indsat 300,00 322,00
2 14 2009-10-13 ny knt. 50,00 50,00
3 12 2009-10-14 hævet 200,00 122,00
Men da beregningen af den nye saldo er sket på baggrund af det sidste ID for en given fk_user så er der gået kuk i posterne, noget i stil med dette:
7 12 2009-10-14 indsat 300,00 322,00
8 14 2009-10-13 ny knt. 50,00 50,00
9 12 2009-10-13 hævet -200,00 100,00
Det som jeg efterlyser er en metode hvor jeg kan gennemløbe (og opdatere) alle posterne for de respekive users (fk_user) og re-beregne den korrekte saldo, i dato orden.
Noget i stil med:
For alle fk_users
postId opdater saldo med (ForrigepostId.saldo+postId.beloeb)
Jeg har overvejet at smidde hele tabellen ud i Excel og gøre det der, da jeg ikke har den fjerneste ide om hvordan man kan
1) løbe tabellen igennem pr. bruger i datoorden
2) updatere saldo på bagrund af den forrige saldo
Any hints (gerne med SQL eksempler) modtages gladeligt
19. oktober 2009 - 22:09
#2
Jeg har den opfattelse af, at vi ikke er helt enige om hvad rimeligt nemt er...
Det jeg gerne ville lave, var en slags løkke der tog
SUM(tidligere poster af Beloeb) og satte det til nuværende post Saldo, for hver enkelt fk_user i stigende datoorden.
Jeg er kommet frem til at jeg må læse lidt op på brugen af cursors, da jeg skal gennekøre denne løkke flere gange.
Først SELECT DISTINCT fk_user
Dernæst for hver fk_user SELECT Beloeb, Saldo ORDER BY Dato
Dernæst skal jeg have grejet hvordan jeg fra en af disse ovestående poster, kan finde den forgående post - sikker noget med at smidde det ind i en #tmp tabel..
02. november 2009 - 21:44
#3
Hej
Her er et eksempel med cursor der løser din opgave:
-- create test table
DROP TABLE loebende
CREATE TABLE loebende(
id bigint IDENTITY(1,1) NOT NULL,
fk_user bigint NOT NULL,
dato datetime NOT NULL,
eventtext varchar(50) NULL,
beloeb bigint NULL,
saldo bigint NULL,
CONSTRAINT PK_loebende PRIMARY KEY CLUSTERED
(id ASC)
)
-- setup test data
delete from loebende
insert into loebende (fk_user, dato, eventtext, beloeb, saldo)
values (12, '2009-10-13', 'indsat', 300, 322)
insert into loebende (fk_user, dato, eventtext, beloeb, saldo)
values (14, '2009-10-13', 'ny knt.', 50, 50)
insert into loebende (fk_user, dato, eventtext, beloeb, saldo)
values (12, '2009-10-14', 'hævet', -200, 122)
SET NOCOUNT ON
DECLARE @lb_fk_user bigint, @lb_dato datetime, @lb_beloeb bigint,
@lb_saldo bigint, @lastdate datetime, @lastuser bigint, @saldo bigint
DECLARE beloeb_cursor CURSOR FOR
SELECT fk_user, dato, beloeb, saldo
FROM loebende
ORDER BY fk_user, dato
OPEN beloeb_cursor
FETCH NEXT FROM beloeb_cursor
INTO @lb_fk_user, @lb_dato, @lb_beloeb, @lb_saldo
set @lastuser = 0;
WHILE @@FETCH_STATUS = 0
BEGIN
if @lb_fk_user <> @lastuser
begin
set @saldo = 0
set @lastuser = @lb_fk_user
end
set @saldo = @saldo + @lb_beloeb
update loebende set saldo = @saldo where current of beloeb_cursor
FETCH NEXT FROM beloeb_cursor
INTO @lb_fk_user, @lb_dato, @lb_beloeb, @lb_saldo
END
CLOSE beloeb_cursor
DEALLOCATE beloeb_cursor
select * from loebende order by fk_user, dato