Firebird ile BORC ALACAK BAKIYE

Firebird ve Interbase veritabanları ve SQL komutlarıyla ilgli sorularınızı sorabilirsiniz. Delphi tarafındaki sorularınızı lütfen Programlama forumunda sorunuz.
Kullanıcı avatarı
rsimsek
Admin
Mesajlar: 4482
Kayıt: 10 Haz 2003 01:48
Konum: İstanbul

Re: Firebird ile BORC ALACAK BAKIYE

Mesaj gönderen rsimsek »

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
Bu şekilde tek SELECT ile bazı ön kabullerle çözüm olabilir. Az veri için pratik bir yöntem olsa da çok miktarda veri olduğunda perfomans kaybını gözönünde bulundurmak lazım. Çünkü her satırda SUM alınıyor.
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')
Diğer bir nokta da matematiksel işlem yapılacak alanların NOT NULL olarak tanımlanması.
NOT NULL olayından kurtulmak için COALESCE() vb.fonksiyonların perfomans kaybına sebep olduğunu akıldan çıkartmamak lazım!
Bilgiyi paylaşarak artıralım! Hayatı kolaylaştıralım!!
abdulkadir
Kıdemli Üye
Mesajlar: 489
Kayıt: 13 Eyl 2003 09:10
Konum: istanbul
İletişim:

Re: Firebird ile BORC ALACAK BAKIYE

Mesaj gönderen abdulkadir »

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 :!:
RECEP ABİ TESEKKÜR EDERİM

denedim ama sorunlu calısıyor
bu işi şimdilik askıya alıcam
biraz ara vereyim sonra tekrar dönerim ins. bir kesin cozum bulursam buraya yazarım.

ilgi ve alakananıza tesekkür ederim saglıcakla kalınız.
Fikirleri Aktar
Kaynakları Dagıt
Ve
Yoldan Çekil
http://www.Leventler.com.tr
Kullanıcı avatarı
rsimsek
Admin
Mesajlar: 4482
Kayıt: 10 Haz 2003 01:48
Konum: İstanbul

Re: Firebird ile BORC ALACAK BAKIYE

Mesaj gönderen rsimsek »

Rica ederim ne demek. Her iki halde de denedim gayet güzel çalışıyor :)
Bilgiyi paylaşarak artıralım! Hayatı kolaylaştıralım!!
abdulkadir
Kıdemli Üye
Mesajlar: 489
Kayıt: 13 Eyl 2003 09:10
Konum: istanbul
İletişim:

Re: Firebird ile BORC ALACAK BAKIYE

Mesaj gönderen abdulkadir »

Her iki halde de denedim gayet güzel çalışıyor
allah allah bende niye dogru calısmadıki
hem order by asc veya desc olması birseyi degisitrmemesi lazım iken
bende ise
asc iken 12000 alacaklıyım
desc olunca 23000 borclu oluyorum :d

neyse saglık olsun size zahmet verdik allah razı olsun
cokta önemli degil en alta bakiyeyi vermek basit oyle yaparız olur biter
Fikirleri Aktar
Kaynakları Dagıt
Ve
Yoldan Çekil
http://www.Leventler.com.tr
smokie
Üye
Mesajlar: 72
Kayıt: 01 Tem 2007 10:26

Re: Firebird ile BORC ALACAK BAKIYE

Mesaj gönderen smokie »

White Rose yazdı:s.a.
Ben de aynı sorunla karşılaşmıştım, aşağıdaki SP ile hallettim

CREATE PROCEDURE MUSHAR_BAKIYE (musnum integer) // musnum müşteri hesap numarası (master-detay link alanı)
as
declare variable bakiye double precision;
declare variable brc double precision;
declare variable odm double precision;
declare variable idn integer;
begin
Bakiye=0;
For
Select MSH_TOP,MSH_ODM,MSH_IDN from mushar // müşteri hareketleri : msh_top>Borç, msh_odm>alacak oluyor
where msh_num=:musnum order by msh_tar,msh_idn // msh_num müşteri kartı ile master-detay bağlantı alanı
into :brc, : odm, :idn
Do Begin
update mushar set
msh_bky=(coalesce(:Brc,0)-coalesce(:Odm,0))+:bakiye
where msh_idn=:idn;
Bakiye=:Bakiye+(coalesce(:Brc,0)-coalesce(:Odm,0));
End
Mrhb,
White Rose
2 gündür ugraşıyorum olmuyor,
master - dety tablo alan isimlerini verebilirmisin çözemedim,
Kullanıcı avatarı
White Rose
Üye
Mesajlar: 726
Kayıt: 06 Tem 2005 09:41
Konum: Güneyden
İletişim:

Re: Firebird ile BORC ALACAK BAKIYE

Mesaj gönderen White Rose »

Müşteri Hareket dosyası MUSHAR
MSH_IDN AUTOINC NOT NULL /* AUTOINC = BIGINT NOT NULL */,
MSH_NUM INTEGER,
MSH_TAR TARIH /* TARIH = DATE */,
MSH_SAAT SAAT /* SAAT = TIME */,
MSH_ISL STR10 /* STR10 = VARCHAR(10) */,
MSH_ACK STR70 /* STR70 = VARCHAR(70) */,
MSH_BRK STR25 /* STR25 = VARCHAR(25) */,
MSH_MIK SMALLINT,
MSH_BRM STR10 /* STR10 = VARCHAR(10) */,
MSH_FYT PARASAL /* PARASAL = DOUBLE PRECISION */,
MSH_TUT PARASAL /* PARASAL = DOUBLE PRECISION */,
MSH_KDV PARASAL /* PARASAL = DOUBLE PRECISION */,
MSH_KTU PARASAL /* PARASAL = DOUBLE PRECISION */,
MSH_ISY PARASAL /* PARASAL = DOUBLE PRECISION */,
MSH_IST PARASAL /* PARASAL = DOUBLE PRECISION */,
MSH_TOP PARASAL /* PARASAL = DOUBLE PRECISION */,
MSH_VTR TARIH /* TARIH = DATE */,
MSH_ODM PARASAL /* PARASAL = DOUBLE PRECISION */,
MSH_OTR TARIH /* TARIH = DATE */,
MSH_BKY PARASAL /* PARASAL = DOUBLE PRECISION */,
MSH_STK INTEGER,
MSH_SPN INTEGER,
MSH_FTN INTEGER,
MSH_STN INTEGER,
DEG_KUL STR15 /* STR15 = VARCHAR(15) */,
DEG_ZMN TARIHSAAT /* TARIHSAAT = TIMESTAMP */

MÜşteri kart dosyası MUSKRT
MSK_IDN AUTOINC NOT NULL /* AUTOINC = BIGINT NOT NULL */,
MSK_NUM INTEGER NOT NULL,
MSK_ADI STR20 /* STR20 = VARCHAR(20) */,
MSK_SOY STR20 /* STR20 = VARCHAR(20) */,
MSK_ADSOY COMPUTED BY (MSK_ADI||' '||MSK_SOY),
MSK_GRB STR20 /* STR20 = VARCHAR(20) */,
MSK_CRK STR01 /* STR01 = VARCHAR(1) */,
MSK_TLF STR15 /* STR15 = VARCHAR(15) */,
MSK_FAX STR15 /* STR15 = VARCHAR(15) */,
MSK_CEP STR15 /* STR15 = VARCHAR(15) */,
MSK_EMAIL STR50 /* STR50 = VARCHAR(50) */,
MSK_ADR1 STR50 /* STR50 = VARCHAR(50) */,
MSK_ADR2 STR50 /* STR50 = VARCHAR(50) */,
MSK_SEH STR30 /* STR30 = VARCHAR(30) */,
MSK_VDA STR30 /* STR30 = VARCHAR(30) */,
MSK_VNO STR20 /* STR20 = VARCHAR(20) */,
MSK_BANKA STR50 /* STR50 = VARCHAR(50) */,
MSK_LMT PARASAL /* PARASAL = DOUBLE PRECISION */,
MSK_LMK BOOLEAN /* BOOLEAN = SMALLINT DEFAULT 0 CHECK (Value in (0,1)) */,
MSK_OZK STR10 /* STR10 = VARCHAR(10) */,
MSK_ACK STR70 /* STR70 = VARCHAR(70) */,
MSK_BRC PARASAL /* PARASAL = DOUBLE PRECISION */,
MSK_ODM PARASAL /* PARASAL = DOUBLE PRECISION */,
MSK_BKY PARASAL /* PARASAL = DOUBLE PRECISION */,
MSK_SMS BOOLEAN DEFAULT 0 /* BOOLEAN = SMALLINT DEFAULT 0 CHECK (Value in (0,1)) */,
MSK_MAIL BOOLEAN DEFAULT 0 /* BOOLEAN = SMALLINT DEFAULT 0 CHECK (Value in (0,1)) */,
DEG_KUL STR15 /* STR15 = VARCHAR(15) */,
DEG_ZMN TARIHSAAT /* TARIHSAAT = TIMESTAMP */

Delphi tarafı SP(Bakiye_Topla)
Bakiye_Topla.Close;
Bakiye_Topla.ParamByName('MUSNUM').AsInteger:=MusharMSH_NUM.AsInteger;
Bakiye_Topla.ExecProc;
Bakiye_Topla.Close;
smokie
Üye
Mesajlar: 72
Kayıt: 01 Tem 2007 10:26

Re: Firebird ile BORC ALACAK BAKIYE

Mesaj gönderen smokie »

tşkler,
olmadı :cry:
Kullanıcı avatarı
Kuri_YJ
Moderator
Mesajlar: 2248
Kayıt: 06 Ağu 2003 12:07
Konum: İstanbul
İletişim:

Re: Firebird ile BORC ALACAK BAKIYE

Mesaj gönderen Kuri_YJ »

Selamlar,

Aşağıdaki Linkte Banka HEsap Ekstresi Hazırlayan bir SP bulacaksınız.

Fikir vermesi açısından yolluyorum.

Kolay Gelsin

viewtopic.php?f=2&t=26863&p=150749#p150749
Kuri Yalnız Jedi
Harbi Özgürlük İçin Pisi http://www.pisilinux.org/
Kullanıcı avatarı
freeman35
Admin
Mesajlar: 2380
Kayıt: 12 Haz 2003 04:05
Konum: merkez camii yanı

Re: Firebird ile BORC ALACAK BAKIYE

Mesaj gönderen freeman35 »

Kod: Tümünü seç

CREATE OR ALTER PROCEDURE SP_AS_EXTRE (
    MST_ID__ BIGINT)
RETURNS (
    PRKEY BIGINT,
    MST_ID BIGINT,
    TARIH DATE,
    ACIKLAMA VARCHAR(255),
    K_ALACAK DOUBLE PRECISION,
    ALACAK DOUBLE PRECISION,
    DOVIZ_ID SMALLINT,
    BORC DOUBLE PRECISION,
    K_BORC DOUBLE PRECISION,
    KISALTMA VARCHAR(3),
    BAKIYE DOUBLE PRECISION,
    IS_BORCLU SMALLINT)
AS
BEGIN
 BAKIYE = 0.0;
  FOR
SELECT M_E.PRKEY, M_E.MST_ID, M_E.TARIH, M_E.ACIKLAMA,
        M_E.K_ALACAK, M_E.ALACAK, M_E.DOVIZ_ID, M_E.BORC,
        M_E.K_BORC, DOVIZ.KISALTMA
    FROM M_EXTRE_DTL M_E
     INNER JOIN DOVIZ ON (M_E.DOVIZ_ID=DOVIZ.PRKEY)
WHERE M_E.MST_ID = || :MST_ID__;    
 ORDER BY M_E.MST_ID, M_E.TARIH, M_E.PRKEY -- Burası önemli çünkü bakiye tarihe göre ilerlemeli
    INTO :PRKEY,
         :MST_ID,
         :TARIH,
         :ACIKLAMA,
         :K_ALACAK,
         :ALACAK,
         :DOVIZ_ID,
         :BORC,
         :K_BORC,
         :KISALTMA
  DO BEGIN
    BAKIYE = :BAKIYE + (:BORC - :ALACAK);
    IF (BAKIYE<0.0) THEN BEGIN
      IS_BORCLU = 0;
    END ELSE BEGIN
     IS_BORCLU = 1;
    END
    SUSPEND;
  END
END
Buda benim yoğurt yiyişim :D bu çalışan müşterimdeki SP
IS_BORCLU değişkenini müşterim -bakiye olmaz dedi, İngilizler anlamıyor bunu dediler bende grid içinde IS_BORCLU 1 se kırmızı renge boyayabilmek için yani sonucun BORÇ olduğunu belirlemek için kullandım

Kolay gele
ZAGOR TENAY TÜRK'tür... TÜRK kalacak...
Zoru başarırım, İmkansız zaman alır
FreeMan 35.5

Soru sormaya üşenmiyorsan, sorunun çözümünü yazmaya da üşenme !!!
haznedarli
Üye
Mesajlar: 122
Kayıt: 31 Tem 2010 06:38

Re: Firebird ile BORC ALACAK BAKIYE

Mesaj gönderen haznedarli »

SELECT CH.BLKODU,CH.TARIHI,CH.EVRAK_NO,CH.ACIKLAMA,CH.ISL EM_TURU,CH.ENTEGRASYON,CH.FATURA_DURUMU,CH.KPB_BTU T AS BORC,CH.KPB_ATUT AS ALACAK,(SELECT SUM(COALESCE(KPB_BTUT, 0))-SUM(COALESCE(KPB_ATUT, 0)) FROM CARIHR WHERE CARIHR.BLCRKODU=CH.BLCRKODU AND CARIHR.TARIHI <= CH.TARIHI) AS BAKIYE FROM CARIHR CH WHERE (CH.BLCRKODU =149) ORDER BY CH.TARIHI ASC


30/01/2010 --- 095729 -------Fatura-------1555-------0------------ 1,555.00
27/02/2010 ----095801-------- Fatura-------2152.5 -----0----------- 3,707.50
16/03/2010-----2799095-------Çek(Müşteri)-----0---- 2541.24------ 1,166.26
20/03/2010 ----095857-------- Fatura--------2953 -------0-----------4,119.26
07/04/2010-----405946--------Çek(Müşteri)-----0---------2500-------4,119.26
07/04/2010-----095930---------Fatura--------2500 --------0----------4,119.26


bu tarih sorununu çözebilecek bir üstat neden yok bu forumda herkezde bir hazır cevap var ama kimse bişi bilmiyor sanırm :D (benim gibi)
haznedarli
Üye
Mesajlar: 122
Kayıt: 31 Tem 2010 06:38

Re: Firebird ile BORC ALACAK BAKIYE

Mesaj gönderen haznedarli »

bu konuda bundaki hesap hep yanlış yapıldı sanırım :=) hakan can ve aslangeri arkadaların yardımı özellikle hakan can arkadaş üstata sonsuz teşekkür ederek onun kodların yolluyarum kullandım ama kusura bakmasın :=)



SELECT
CH.BLKODU,
CH.TARIHI,
CH.EVRAK_NO,
CH.ACIKLAMA,
CH.ISLEM_TURU,
CH.ENTEGRASYON,
CH.FATURA_DURUMU,
CH.KPB_BTUT AS BORC,
CH.KPB_ATUT AS ALACAK,
(SELECT ABS(COALESCE(SUM(KPB_BTUT), 0) - COALESCE(SUM(KPB_ATUT), 0)) FROM CARIHR WHERE CARIHR.BLCRKODU = CH.BLCRKODU AND ((CARIHR.TARIHI < CH.TARIHI) OR (CARIHR.TARIHI = CH.TARIHI AND CARIHR.BLKODU <= CH.BLKODU))) AS BAKIYE,
CASE WHEN (SELECT COALESCE(SUM(KPB_BTUT), 0) - COALESCE(SUM(KPB_ATUT), 0) FROM CARIHR WHERE CARIHR.BLCRKODU = CH.BLCRKODU AND ((CARIHR.TARIHI < CH.TARIHI) OR (CARIHR.TARIHI = CH.TARIHI AND CARIHR.BLKODU <= CH.BLKODU))) > 0 THEN 'Borç'
WHEN (SELECT COALESCE(SUM(KPB_BTUT), 0) - COALESCE(SUM(KPB_ATUT), 0) FROM CARIHR WHERE CARIHR.BLCRKODU = CH.BLCRKODU AND ((CARIHR.TARIHI < CH.TARIHI) OR (CARIHR.TARIHI = CH.TARIHI AND CARIHR.BLKODU <= CH.BLKODU))) < 0 THEN 'Alacak' END AS BORC_ALACAK
FROM CARIHR CH
WHERE (CH.BLCRKODU = 149)
ORDER BY CH.TARIHI, CH.BLKODU
Kullanıcı avatarı
esistem
Üye
Mesajlar: 464
Kayıt: 02 Eki 2007 11:22
İletişim:

Re: Firebird ile BORC ALACAK BAKIYE

Mesaj gönderen esistem »

Uzun zaman sonra konuyu yinede aktif görmek güzel :)

Bu konuda kendi çözümümü sunmak istiyorum zira ilk açıldığı zamanda incelemiştim konuyu ve çözümü şöyle üretmiştim;

Cari hesap hareketleri;
Fatura girişi, çek/senet girişi, kasa işlemi(tahsilat/ödeme) vb. gibi durumlarda hareket keydeder sonuçta.
bende şöyle bir çözüm buldum du buna;
CARI_ISLEM tablosunun ID alanından sonra sira isimli bir alan daha ekledim int değerli, varsayılanı '0' olarak.

fatura, kasa, cek/senet tablolarının beforeinsert ve beforeupdate olaylarına da

Kod: Tümünü seç

declare variable ARTAN INTEGER;
declare variable KAYITKODU INTEGER;

ARTAN=0;
for select KOD from CARI_ISLEM WHERE CARI_KODU=NEW.CARI_KODU order by TARIH
into :KAYITKODU do begin
ARTAN=ARTAN+1; update CARI_ISLEM set SIRA = :ARTAN where (kod = :KAYITKODU);
                             end
Kodunu ekledim.
böylece hem tarih olayını iptal etmiş hemde sorguyu int bir alanla yapmış oldum.

sorgumda şu şekilde

Kod: Tümünü seç

SELECT I.KOD, I.TARIH, I.ISLEM_KODU, I.ISLEM_TURU, I.OPSIYON, 
I.BORC, I.ALACAK, I.BAKIYE, I.ACIKLAMA, 
COALESCE(
       (SELECT SUM(BORC) - SUM(ALACAK) FROM CARI_ISLEM
           WHERE CARI_ISLEM.CARI_KODU = :KOD AND CARI_ISLEM.SIRA<=I.SIRA), 0) AS BAKIYE1
FROM CARI_ISLEM I WHERE I.CARI_KODU =:KOD
ORDER BY I.SIRA
bu şekilde yapınca asc veya desc desenizde hiçbi sorun çıkmıyor hesaplarda.
birde NOTNULL alan kullanırsanız sorguda COALESCE kullanmanızada hiç gerek kalmaz.

Saygılar...
haznedarli
Üye
Mesajlar: 122
Kayıt: 31 Tem 2010 06:38

Re: Firebird ile BORC ALACAK BAKIYE

Mesaj gönderen haznedarli »

özür dlerim ben sonucu buraya yazmayı unuttum yanlış dediğim sorgu süper onumara çalışıyor benim muhasebe programımda sıralama yanlış oldugundan sorun cıkıyormuş sorguya göre yaptım bende sıralamayı muhasebe programında sorunsuzdur su anda tekrar özürdilerim..
akuyumcu63
Üye
Mesajlar: 386
Kayıt: 02 Tem 2007 09:43

Re: Firebird ile BORC ALACAK BAKIYE

Mesaj gönderen akuyumcu63 »

merhaba;

Kod: Tümünü seç

SELECT CH.ID,CH.CARIID,CH.TARIH,CH.BORC AS BORC,CH.ALACAK AS ALACAK,
          (SELECT ABS(COALESCE(SUM(BORC),0) - COALESCE(SUM(ALACAK),0)) FROM TBLCARIHAR WHERE TBLCARIHAR.ID=CH.ID AND 
                               ((TBLCARIHAR.TARIH<=CH.TARIH) OR (TBLCARIHAR.TARIH=CH.TARIH) OR (TBLCARIHAR.TARIH>=CH.TARIH))) as bakiye
FROM TBLCARIHAR CH
WHERE (CH.CARIID=23)
ORDER BY ID, TARIH
yukarıdaki kod borc-alacak yapıyor. artan bakiye neden yapmıyor neyi eksik bırakıyorum.

kolay gelsin;
İsteyen, yapabildiğinden daha fazlasını yapar.
Kullanıcı avatarı
Kuri_YJ
Moderator
Mesajlar: 2248
Kayıt: 06 Ağu 2003 12:07
Konum: İstanbul
İletişim:

Re: Firebird ile BORC ALACAK BAKIYE

Mesaj gönderen Kuri_YJ »

Selamlar,

Tarih kriterinde bütün tarihleri almışsın ;) Artan bakiye için o andaki kaydın tarih ve ID'sine göre sıralama yaptırman lazım.

Kolay Gelsin
Adnan
Kuri Yalnız Jedi
Harbi Özgürlük İçin Pisi http://www.pisilinux.org/
Cevapla