Kod: Tümünü seç
SELECT
CH.TARIHI,
CH.BLKODU, CH.KPB_ATUT AS ALACAK,
CH.KPB_BTUT AS BORC,
(SELECT SUM(COALESCE(KPB_ATUT, 0)) - SUM(COALESCE(KPB_BTUT, 0)) FROM CARIHR
WHERE CARIHR.BLCRKODU = CH.BLCRKODU
AND CARIHR.BLKODU <= CH.BLKODU AND CARIHR.TARIHI <= CH.TARIHI) AS BAKIYE
FROM CARIHR CH WHERE (CH.BLCRKODU = 10)
ORDER BY CH.TARIHI
Stored Procedure ile ise tablodaki aynı veriyi döndürecek bir SP ile ORDER BY a dikkat ederek, verilen tarih öncesini toplayıp farkını alıp DEVİR satırı olarak dışarı veren, sonra da bu devirin üzerinden BAKİYEYİ her satırda yeniden hesaplayıp yürütmek gerekiyor.
Her iki yöntemde de aynı tarihli kayıtları ayırt etmek için kullanılan ID için sonradan geçmiş tarihli kayıtlardan dolayı sorun çıkabilir

SP örneği;
Kod: Tümünü seç
CREATE OR ALTER PROCEDURE SP_YURUYEN_BAKIYE(
CARI_KODU DOUBLE PRECISION,
ILK_TARIH DATE,
SON_TARIH DATE)
RETURNS (
TARIHI DATE,
BORC DOUBLE PRECISION,
ALACAK DOUBLE PRECISION,
BAKIYE DOUBLE PRECISION)
AS
DECLARE DLR_BORC DOUBLE PRECISION;
DECLARE DLR_ALACAK DOUBLE PRECISION;
DECLARE DLR_BAKIYE DOUBLE PRECISION;
BEGIN
SELECT
SUM(COALESCE(KPB_ATUT,0)), SUM(COALESCE(KPB_BTUT,0))
FROM CARIHR
WHERE BLCRKODU = :CARI_KODU AND TARIHI < :ILK_TARIH
INTO
:DLR_BORC,
:DLR_ALACAK;
TARIHI = ILK_TARIH;
BORC = DLR_BORC;
ALACAK = DLR_ALACAK;
BAKIYE = DLR_ALACAK - DLR_BORC;
SUSPEND; -- Toplanan ilk_tarih öncesinin devrini döndür.
FOR
SELECT
TARIHI, KPB_ATUT, KPB_BTUT
FROM CARIHR
WHERE BLCRKODU = :CARI_KODU
AND TARIHI >= :ILK_TARIH AND TARIHI <= :SON_TARIH
ORDER BY TARIHI, BLKODU -- her bir kayıtı ayırt etmek için kullanılan bu ID alanı (BLKODU)
INTO -- sonradan girilen geriye dönük eski tarihli kayıtlar için sorun oluşturacaktır!!!
:TARIHI,
:ALACAK,
:BORC
DO BEGIN
BAKIYE = :BAKIYE + (COALESCE(:ALACAK, 0) - COALESCE(:BORC, 0));
SUSPEND;
END
END
Kod: Tümünü seç
SELECT TARIHI, BORC, ALACAK, BAKIYE
FROM SP_YURUYEN_BAKIYE(10, '11.06.2008', '23.10.2008')
NOT NULL olayından kurtulmak için COALESCE() vb.fonksiyonların perfomans kaybına sebep olduğunu akıldan çıkartmamak lazım!