[ virtual zubo @ 01.03.2010. 10:11 ] @
MS SQL 2005. Prva tabela prikazuje recimo dugovanja po datumima, a druga uplate .
Potrebno je bez koristenja kursora po ID oduzimati uplate od zaduzenja tako da na kraju ostane recimo

id datum iznos
1 2010-01-01 00:00:00.000 0.00
1 2010-02-01 00:00:00.000 60.00
1 2010-03-01 00:00:00.000 100.00
1 2010-04-01 00:00:00.000 100.00

za ID = 1.

primer za test :

CREATE TABLE #prva
(id INT, datum DATETIME, iznosDuga MONEY)

CREATE TABLE #druga
(id INT, ukupnoUplatio MONEY)

INSERT INTO #prva VALUES (1,'2010-01-01',100)
INSERT INTO #prva VALUES (1,'2010-02-01',100)
INSERT INTO #prva VALUES (1,'2010-03-01',100)
INSERT INTO #prva VALUES (1,'2010-04-01',100)
INSERT INTO #prva VALUES (2,'2010-02-01',100)
INSERT INTO #prva VALUES (2,'2010-02-10',100)
INSERT INTO #prva VALUES (2,'2010-03-20',100)
INSERT INTO #prva VALUES (2,'2010-03-25',10)
INSERT INTO #prva VALUES (2,'2010-04-01',100)
INSERT INTO #prva VALUES (3,'2010-01-01',200)
INSERT INTO #prva VALUES (3,'2010-02-01',300)
INSERT INTO #prva VALUES (3,'2010-03-21',100)

INSERT INTO #druga VALUES (1,140)
INSERT INTO #druga VALUES (2,250)
INSERT INTO #druga VALUES (3,550)


ja sam nesto pokusavao, ali bez uspeha.
Hvala na pomoci, nadam se da ce resenje da koristi jos nekome.


p.s. potencijalno tabela #prva je velika tj ima cca nekoliko stotina hiljada id-ova i ovakav nacin bi drasticno ubrzao
[ Fedya @ 01.03.2010. 10:28 ] @
nesto kao:

Code:

select p.id, sum(iznosDuga) - (select ukupnoUplatio from #druga d where p.Id = d.Id)  as dug
from #prva p
group by p.id


ignorisao sam datume, posto nemas datum uplate, pa ne mozemo znati na koji dan je koliko dugovao.
[ sparc @ 01.03.2010. 12:29 ] @
Ovo mi lici na otvorene stavke u knjigovodstvu, gde imas u jednoj tabeli racune
a u drugoj tabeli uplate, koje se povezuju preko ID za partnera, stim da su u
tvojoj tabelu za uplate sve uplate koje su se desile kumulirane kroz polje
ukupne uplate i ti sada trebas hronoloski za zatvoris racune i da vidis koliko
ti je po kom racunu ostalo za naplatu.
Ovo je nemoguce izvesti kroz jedan prolaz, jer uplate realizuju jedan ili vise racuna,
a pored toga za resenje ovog problema ti nedostaju i neka dodatna polja, u
tabeli 1 uplaceni iznos, u tabeli 2 nezatvorena uplata.
Ti treba da azuriras kroz jedan upit obe tabele tako sto ces sekvencijalno
da citas prvu tabelu po datumu racuna i da azuriras polje uplaceni iznos, sve dok
imas "zalihe" u polju neztvorena uplata u tabeli uplata.
Ja mislim da ovo nije moguce izvesti kroz jedan Update.
[ virtual zubo @ 01.03.2010. 15:42 ] @
Nije za knjigovodstvo, al nije ni bitno, bitno je da kad se srede podaci na kraju se dobiju 2 tabele struktura koje su date. Kursorom moze da se resi i to svako zna da napise na ovaj ili onaj nacin, a mislim da moze i jednim updateom. Uskoro ce da mi dodja "na kanal"
ovaj problem pa cu da mu posvetim duzno vreme, al sam mislio da ako je neko vec odradio da ne otkrivam toplu vodu :)


"ignorisao sam datume, posto nemas datum uplate, pa ne mozemo znati na koji dan je koliko dugovao"

datum uplate nije vazan jer se radi sum(uplate) na neki datum (recimo u primeru da je to 1.april 2010.), ali datumi zaduzenja jesu bitni jer na kraju treba da dobijem:
id datum iznos
1 2010-01-01 00:00:00.000 0.00
1 2010-02-01 00:00:00.000 60.00
1 2010-03-01 00:00:00.000 100.00
1 2010-04-01 00:00:00.000 100.00

sto mi govori da covek duguje od 1.feb 260 dinara, cega god ...

u principu je svejedno kako ce da se resi ali mislim da je update neuporedivo brzi od kursoskog resenja (brzina mi je vazna ovde, ali tacnost je najvaznija).

hvala
[ HladankaoLed @ 02.03.2010. 10:11 ] @
Pozdrav,

nisam siguran da sam bas razumeo zasto u naslovu posta stoji UPDATE statement, kada ti zelis samo da procitas tabelu sa zaduzenjima, sa osvrtom na sve uplate...

Anyway, evo jednog resenja - nadam se da u sebi nema gresaka, za to, nazalost, zbog vremena ne mogu da garantujem, ali mozes sam to da proveris. U svakom slucaju resenje je barem putokaz kako se ovaj problem moze resiti bez primene kursora.

Code:
;
WITH cte AS
(
SELECT id, datum, iznosDuga,
(SELECT SUM(iznosDuga) FROM #prva pr2 WHERE pr1.id = pr2.id AND pr1.datum >= pr2.datum) iznosDugaAccumulated,
(SELECT ISNULL(SUM(ukupnoUplatio),0) FROM #druga dr WHERE dr.id=pr1.id) Uplatio
FROM #prva pr1
)

SELECT id, datum,
CASE WHEN iznosDugaAccumulated<=Uplatio
    THEN 0 
    ELSE
        CASE WHEN iznosDugaAccumulated - Uplatio > iznosDuga 
            THEN iznosDuga
            ELSE iznosDugaAccumulated - Uplatio
        END
END OstatakDugovanja
FROM cte  


Sto se tice performansi, uz ovo resenje podrazumevajuci su cluster indeksi na id polju, te noncludtered index na poljima id, datum u prvoj tabeli.

Pozdrav,
[ virtual zubo @ 02.03.2010. 11:56 ] @
"nisam siguran da sam bas razumeo zasto u naslovu posta stoji UPDATE statement"
u pravu si, mislio sam da uradim

update #Prva
set iznosDuga = ....

pa sam zato u naslovu stavio UPDATE

pogledao sam malo ovo tvoje resenje i deluje mi dobro , ustvari ni ne mora update da se radi, gledao sam pogresno

cim stignem probacu da ga propustim kroz realnu kolicinu podataka

hvala