1

Konu: kümulatif toplam

selamlar;

Diyelimki aşağıdaki gibi bir cursor var.
Yanlız kümulatif miktarları yazılı değil.
Sql komutları ile veya başka bir yöntem ile nasıl otomatik kümulatif toplamı aldırta bilirim.



kod    mik    ay    kümulatif mik
a    2    1    2
a    9    2    11
a    5    3    16
a    1    4    17
b    5    1    5
b    7    3    12
b    3    5    15

Teşekkürler.

Bilmediğin Neyse Yanıldığındır.

2

Re: kümulatif toplam

Visual Fox Pro
SELECT t1.kod, t1.mik, t1.ay, sum(t2.mik) as kumulatif ;

FROM myTable t1 ;
LEFT JOIN myTable t2 ;
ON t1.kod == t2.kod AND t1.ay >= t2.ay ;
group BY 1,3,2

3

Re: kümulatif toplam

teşekkür ederim.

Bilmediğin Neyse Yanıldığındır.

4

Re: kümulatif toplam

merhabalar,
ay sonu stok raporu almak istiyorum. stok hareket dosyam var
kod,giris,cikis,tarihirs alanları var
her ürün için her ayın sonunda stok miktarı neymiş onu görmek istiyorum. yardımcı olabilirseniz sevinirim

Kader, beyaz kağıda sütle yazılmış yazı
Elindeyse beyazdan, gel de sıyır beyazı. (NFK)

5

Re: kümulatif toplam

tarik;

[email protected]'a  xls olarak gönderebilirsen yardımcı olabileceğimi düşünüyorum.

Bilmediğin Neyse Yanıldığındır.

6

Re: kümulatif toplam

selamlar,
Set ENGINEBEHAVIOR 70 &&& vfp 9.0 ise
Select kod,Month(tarihirs) ay,Sum(giris) From aystok Group By kod,2 Into Cursor sonuc1
Local oXtab
Select sonuc1
oXtab = Newobject("FastXtab", "FastXtab.prg")
oXtab.nPageField = 1
oXtab.nRowField = 2
oXtab.nColField = 3
oXtab.nDataField = 4
oXtab.lCursorOnly = .T.
oXtab.lBrowseAfter = .F.
oXtab.lCloseTable = .F.
oXtab.RunXtab()
Select FastXtab
Browse

bu kodda sadece giriş miktarına göre işlem yaptırıyorsun , o dsoyada hem giriş var hemde çıkış

Kader, beyaz kağıda sütle yazılmış yazı
Elindeyse beyazdan, gel de sıyır beyazı. (NFK)

7

Re: kümulatif toplam

1.    create cursor aystok (kod c(10), tarihirs d(8),giris n(8),cikis n(8))
2.    insert into aystok values ('3516','27/12/2006',27,0)
3.    insert into aystok values ('3516','02/01/2007'0,10)
4.    insert into aystok values ('3516','18/02/2007',15,0)
5.    insert into aystok values ('3516','28/02/2007'0,4)
böyle bir dosyadan yola çıkarak

kod     ocak    şubat    mart
3516    17    28    28   
?..
?..

Gibi bir stok raporu almak

Kader, beyaz kağıda sütle yazılmış yazı
Elindeyse beyazdan, gel de sıyır beyazı. (NFK)

8 Son düzenleyen, ugurlu2001 (13.03.2007 10:27:28)

Re: kümulatif toplam

Visual Fox Pro
SET DATE TO BRITISH 

SET CENTURY ON
 
create cursor aystok (kod c(10), tarihirs d(8),giris n(8),cikis n(8))
insert into aystok values ('3516',CTOD('27/12/2006'),27,0)
insert into aystok values ('3516',CTOD('02/01/2007'),0,10)
insert into aystok values ('3516',CTOD('18/02/2007'),15,0)
insert into aystok values ('3516',CTOD('28/02/2007'),0,4)
 
 
Ay_Kontur = 1
 
DO WHILE Ay_Kontur <= 12 && Her ay için Toplamları oluşturalım...
 
    IF Ay_Kontur < 10
        TempCursor = "Ay_0"+ALLTRIM(STR(Ay_Kontur))
    ELSE
        TempCursor = "Ay_"+ALLTRIM(STR(Ay_Kontur))
    ENDIF
 
    SELECT ;
        AyStok.Kod AS Kod, ;
        SUM(AyStok.Giris) AS Giris, ;
        SUM(AyStok.Cikis)  AS Cikis ;
        FROM AyStok ;
        WHERE MONTH(AyStok.Tarihirs) = Ay_Kontur ;
        GROUP BY AyStok.Kod ;
        INTO CURSOR &TempCursor
    Ay_Kontur = Ay_Kontur +1
 
ENDDO
 
SET

*/ Her ay için, koda göre gruplu olarak  toplamların bulunduğu CURSOR oluşturuldu ...
*/ Bu kod işinizi görür. Kolay gelsin ....

Uğur
-------------------------------------------------------------------------------------------------------------
Hayat bir bisiklete binmek gibidir. Pedalı çevirmeye devam ettiğiniz sürece düşmezsiniz. Claude Peppeer
Kusuru söylenmeyen adam, ayıbını hüner sanır.  Türk Atasözü

9 Son düzenleyen, foxman (16.03.2007 12:18:26)

Re: kümulatif toplam

Tek satırda kumulatif.

Visual Fox Pro
CREATE CURSOR dene (n1 n(3),kumulatif n(5))

SELECT dene
FOR i=1 TO 10
    INSERT INTO dene (n1) VALUES (INT(rand()*10))
ENDFOR
 
REPLACE ALL kumulatif WITH ;
EXECSCRIPT("rsakla=RECNO()"+CHR(13)+"skip -1"+CHR(13)+"pkumulatif=kumulatif"+CHR(13)+"go rsakla"+CHR(13)+"return pkumulatif+n1"+CHR(13))
 
GO top
BROWSE LAST

10

Re: kümulatif toplam

Foxman,
Belki benim anlamadigim bir numara kodda ama Tarik'in istedigi toplami veya herhangi bir kumulatif toplami bu kod nasil alir anlamadim. Senin ornek cursor ile alir da herhangi bir tabloda bu is nasil olur kafam basmadi.

Diyelimki ben anlamamisim oluyor, niye execscript()? Sadece satir sayisini azaltmak icin mi? Satir sayisi azalir, tabii beraberinde dramatik bir sekilde hiz da azalir. Bu kodu hic:
for i=1 to 10000
ile denedin mi?

Execscript() de sorun olmadi diyelim, neden onsuz hali varken recno() sakla skip, go vs gereksiz kod calissin?

Bak mesela bu da kotu ama daha efektif:

Visual Fox Pro
CREATE CURSOR dene (n1 n(3),kumulatif n(5))

FOR i=1 TO 10
  INSERT INTO dene (n1) VALUES (INT(rand()*10))
ENDFOR
use dbf('dene') again in 0 alias 'dene2'
select dene
set relation to recno()-1 into dene2
 
REPLACE ALL kumulatif WITH dene2.kumulatif+n1
LOCATE
USE IN 'dene2'
BROWSE LAST

11

Re: kümulatif toplam

Tarik,
Bu arada senin sorun icin 2 parcali bir cevap. Birinci parca kumulatif toplami dikine tabloya aliyor. Ikinci parca o tabloyu yatay dagitiyor (Crosstab, xtab islemi):

Visual Fox Pro
create cursor aystok (kod c(10), tarihirs d(8),giris n(8),cikis n(8))

insert into aystok values ('3516',{^2006/12/27},27,0)
insert into aystok values ('3516',{^2007/01/02},0,10)
insert into aystok values ('3516',{^2007/02/18},15,0)
insert into aystok values ('3516',{^2007/02/28},0,4)
 
aylar = 'Ocak,Subat,Mart,Nisan,Mayis,Haziran,Temmuz,Agustos,Eylul,Ekim,Kasim,Aralik'
 
SELECT kod, ;
    YEAR(tarihirs) as yil, ;
    MONTH(tarihirs) as nAy, ;
    SUM(giris-cikis) as stok ;
    FROM aystok ;
    GROUP BY 1,2,3 ;
    INTO CURSOR topStok
 
SELECT t1.kod, t1.yil, ;
    PADR(GETWORDNUM(m.aylar,t1.nAy,','),10) as ay, ;
    t1.nAy, sum(t2.stok) as kumulatif ;
FROM topStok t1 ;
LEFT JOIN topStok t2 ;
ON t1.kod == t2.kod AND DATE(t1.yil,t1.nAy,1) >= DATE(t2.yil,t2.nAy,1) ;
group BY 1,2,3,4 ;
ORDER BY 1,4,2 ;
INTO CURSOR tmpKumulatif
 
CrossTab('tmpKumulatif','Kumulatif','yil,kod','ay','kumulatif')
browse

12

Re: kümulatif toplam

Visual Fox Pro
*CrossTab.prg

Lparameters tcSource,tcTarget,tcRowFields,tcColumnField, tcDataField
LOCAL ix,lcConnect
LOCAL ARRAY aCols[1]
SELECT distinct &tcRowFields, SPACE(10) as uid ;
    FROM (m.tcSource) ;
    INTO CURSOR __crsUID ;
    readwrite
replace ALL uid WITH SYS(2015)
 
SET TEXTMERGE TO memvar m.lcConnect noshow
SET TEXTMERGE on
FOR ix = 1 TO ALINES(aCols,m.tcRowFields,.t.,',')
\\<<IIF(m.ix > 1,' and ','')>>lft.<<aCols[m.ix]>> == rgt.<<aCols[m.ix]>>
endfor
SET TEXTMERGE to
SET TEXTMERGE off
 
SELECT lft.*, rgt.uid ;
    FROM (m.tcSource) lft ;
    INNER JOIN __crsUID rgt ON &lcConnect ;
    INTO CURSOR __crsTemp ;
    nofilter
 
* Cross tab data
* tcSource,tcTarget,tcRowField,tcColumnField, tcDataField
CreateCrossTab('__crsTemp','__crsXTab','uID',m.tcColumnField, m.tcDataField)
 
SET TEXTMERGE TO memvar m.lcFields noshow
SET TEXTMERGE on
FOR ix = 1 TO ALINES(aCols,m.tcRowFields,.t.,',')
\\<<IIF(m.ix > 1,',','')>>t1.<<aCols[m.ix]>>
endfor
SET TEXTMERGE to
SET TEXTMERGE off
 
IF USED(m.tcTarget)
    USE IN (m.tcTarget)
endif
SELECT DISTINCT &lcFields,t2.* ;
    FROM __crsTemp t1 ;
    INNER JOIN __crsXtab t2 ;
    ON t1.UID == t2.UID ;
    INTO CURSOR (m.tcTarget) ;
    readwrite
ALTER table (m.tcTarget) drop COLUMN uid
USE IN '__crsUID'
USE IN '__crsXTab'
USE IN '__crsTemp'
 
Function CreateCrossTab
    Lparameters tcSource,tcTarget,tcRowField,tcColumnField, tcDataField
    Local ix,lcType,lnLen,lnDec,lcType1,lnLen1,lnDec1,lcLeft,lcRight
    Local Array aStruct[1],aCols[1], aXTab[1]
    For ix=1 To Afields(aStruct,m.tcSource)
        If Upper(Trim(m.tcRowField)) == Upper(Trim(aStruct[m.ix,1]))
            lcType1 = aStruct[m.ix,2]
            lnLen1  = aStruct[m.ix,3]
            lnDec1  = aStruct[m.ix,4]
        Endif
        If Upper(Trim(m.tcDataField)) == Upper(Trim(aStruct[m.ix,1]))
            lcType = aStruct[m.ix,2]
            lnLen  = aStruct[m.ix,3]
            lnDec  = aStruct[m.ix,4]
        Endif
    Endfor
 
    SELECT &tcColumnField,SYS(2015) as orderby ;
        FROM (m.tcSOurce) ;
        INTO CURSOR __xorder__ ;
        nofilter
    lcLeft  = 't1.'+m.tcColumnField
    lcRight = 't2.'+m.tcColumnField
    SELECT t1.orderby,&tcColumnField ;
        FROM __xorder__ t1 ;
        WHERE t1.orderby == ;
        (select MIN(orderby) FROM __xorder__ t2 ;
        WHERE &lcLeft == &lcRight ) ;
        ORDER BY 1 ;
        INTO cursor __sortCols__
    SELECT &tcColumnField ;
        FROM __sortCols__ ;
        INTO ARRAY aCols
    USE IN '__xorder__'
    USE IN '__sortCols__'
 
    Dimension aXTab[Alen(aCols)+1,5]
    aXTab[1,1] = m.tcRowField
    aXTab[1,2] = m.lcType1
    aXTab[1,3] = m.lnLen1
    aXTab[1,4] = m.lnDec1
    aXTab[1,5] = .f.
    For ix=1 To Alen(aCols)
        aXTab[m.ix+1,1] = Chrtran(Trim(aCols[m.ix]),' ','_')
        aXTab[m.ix+1,2] = m.lcType
        aXTab[m.ix+1,3] = m.lnLen
        aXTab[m.ix+1,4] = m.lnDec
        aXTab[m.ix+1,5] = .t.
    Endfor
    Create Cursor (m.tcTarget) From Array aXTab
    Local Array arrRec[Floor(65000/Fcount()),Fcount()]
    arrRec = .null.
    Select Distinct &tcRowField As _RowData ;
        from (m.tcSource) ;
        into Cursor _DRows
    lnRec = 0
    Scan
        If m.lnRec = 65000
            Insert Into (m.tcTarget) From Array arrRec
            arrRec = .F.
            lnRec = 0
        Endif
        lnRec = m.lnRec + 1
        arrRec[m.lnRec,1] = _DRows._RowData
        Select (m.tcSource)
        Scan For Evaluate(m.tcRowField) = arrRec[m.lnRec,1]
            arrRec[m.lnRec, ;
        Asubscript(aXTab, ;
        Ascan(aXTab,;
        Chrtran(Trim(;
        Evaluate(m.tcSource+'.'+m.tcColumnField)),' ','_')),1)] = ;
                Evaluate(m.tcSource+'.'+m.tcDataField)
        Endscan
        Select (m.tcSource)
    Endscan
    Use In '_DRows'
    Dimension arrRec[m.lnRec,Alen(arrRec,2)]
    Insert Into (m.tcTarget) From Array arrRec
    Select (m.tcTarget)
    Locate
Endfunc

13 Son düzenleyen, foxman (19.03.2007 00:39:08)

Re: kümulatif toplam

Çetin,
Ben o kodu oraya sadece fikir jimlastiği olsun diye koydum. Doğru execscript her satırda compile edildiği için oldukça yavaş çalısıyor.

14 Son düzenleyen, foxman (18.03.2007 22:15:18)

Re: kümulatif toplam

Yanlız ben şu kumulatif toplam konusuna biraz değinmek istiyorum. Cumulative'in sözlük manası "gittikçe artan" demek. Yani rakam içeren bir kolonunuz varsa yanına bu rakamların değerlerini  toplayarak bir kumulatif kolonu oluşturabilirsiniz. Bence aylık veya başka dönemler için kumulatif toplam almak yerine kumulatif kolonu oluşturmak kavramı daha doğru, bu tip kumulatif kolonlar bazı satış analizleri için kullanılabiliyor.

Eğer bir tane table varsa, ikinci bir table oluşturmadan table'ı ikinci defa açmadan kumulatif kolonu oluşturmak için. Aşağıdaki kodlar kullanılabilir.

Eğer herhangi bir gruplama ihtiyacı yoksa.

Visual Fox Pro
CREATE CURSOR dene (kod c(2),ay c(2),miktar n(3),kumulatif n(10))

SELECT dene
FOR i=1 TO 1000
  INSERT INTO dene (kod,ay,miktar) VALUES (TRANSFORM(INT(rand()*10)+1,"@L ##"),TRANSFORM(INT(rand()*12)+1,"@L ##"),INT(rand()*10))
ENDFOR
 
pkumulatif=0
SCAN
    REPLACE kumulatif WITH miktar+pkumulatif
    pkumulatif=kumulatif
ENDSCAN
 
GO top
BROWSE LAST

Gruplama ihtiyacı varsa.

Visual Fox Pro
CREATE CURSOR dene (kod c(2),ay c(2),miktar n(3),kumulatif n(10))

SELECT dene
FOR i=1 TO 1000
  INSERT INTO dene (kod,ay,miktar) VALUES (TRANSFORM(INT(rand()*10)+1,"@L ##"),TRANSFORM(INT(rand()*12)+1,"@L ##"),INT(rand()*10))
ENDFOR
INDEX on kod+ay TAG koday
 
ckoday=kod+ay
pkumulatif=0
SCAN
    IF ckoday=kod+ay
        REPLACE kumulatif WITH miktar+pkumulatif
        pkumulatif=kumulatif
    ELSE
        ckoday=kod+ay
        REPLACE kumulatif WITH miktar
        pkumulatif=kumulatif
    ENDIF
ENDSCAN
 
GO top
BROWSE LAST

15 Son düzenleyen, foxman (18.03.2007 23:10:27)

Re: kümulatif toplam

Tarık'ın sorusuna gelince.

Tarık "her ürün için her ayın sonunda stok miktarı neymiş onu görmek istiyorum" demiş. Kumulatif toplam değil aylık dönemler sonundaki "Stok durumunu" görmek istiyor.

Bu işi join veya relation kurmadan table'ı ikinci defa açmadan index ihtiyacı olmadan aşağıdaki tek bir query'ile yapması mümkün.

Query deki iif'ler sürekli çalışacağı için kod yavaş çalışır diyebilirsiniz, join veya relation kullanıldığında record pointer sürekli hem cdx içinde hemde table içinde dolaştığı içinde yavaşlıyor. Ayrıca xtab, crosstab programları yüksek sayıda kayıt içeren table'larda aşırı yavaşlayıp çuvallayabiliyor, tabi programın crosstab içindeki bir sürü kodu çalıştırmak zorunda olması da cabası.

Aşağıdaki query'nin şöyle bir avantajı daha var, eğer sonuçları ekrandan gösteren ve 12 kolon içeren bir grid'iniz varsa veya 12 kolon içeren bir raporunuz varsa onlarla oynamak zorunda kalmazsınız çünkü query sürekli 12 kolon oluşturur ayrıca NULL değer içeren kolonlar oluşmaz. Birde group by da kullanacağınız kolon sayısı query nin kapasitesi kadar çok olabiliyor.

Visual Fox Pro
Create Cursor aystok (kod c(10), tarihirs d(8),giris N(8),cikis N(8))

Insert Into aystok Values ('3516',{^2006/12/27},27,0)
Insert Into aystok Values ('3516',{^2007/01/02},0,10)
Insert Into aystok Values ('3516',{^2007/02/18},15,0)
Insert Into aystok Values ('3516',{^2007/02/28},0,4)
 
Select Year(tarihirs) As yil,kod, ;
    SUM(Iif(Month(tarihirs)= 1,giris-cikis,0)) As "OCAK", ;
    SUM(Iif(Month(tarihirs)= 2,giris-cikis,0)) As "SUBAT", ;
    SUM(Iif(Month(tarihirs)= 3,giris-cikis,0)) As "MART", ;
    SUM(Iif(Month(tarihirs)= 4,giris-cikis,0)) As "NISAN", ;
    SUM(Iif(Month(tarihirs)= 5,giris-cikis,0)) As "MAYIS", ;
    SUM(Iif(Month(tarihirs)= 6,giris-cikis,0)) As "HAZIRAN", ;
    SUM(Iif(Month(tarihirs)= 7,giris-cikis,0)) As "TEMMUZ", ;
    SUM(Iif(Month(tarihirs)= 8,giris-cikis,0)) As "AGUSTOS", ;
    SUM(Iif(Month(tarihirs)= 9,giris-cikis,0)) As "EYLUL", ;
    SUM(Iif(Month(tarihirs)=10,giris-cikis,0)) As "EKIM", ;
    SUM(Iif(Month(tarihirs)=11,giris-cikis,0)) As "KASIM", ;
    SUM(Iif(Month(tarihirs)=12,giris-cikis,0)) As "ARALIK" ;
    FROM aystok ;
    GROUP By 1,2 Into Cursor q1
 
Browse Last

16

Re: kümulatif toplam

foxman yazdı:

Yanlız ben şu kumulatif toplam konusuna biraz değinmek istiyorum. Cumulative'in sözlük manası "gittikçe artan" demek. Yani rakam içeren bir kolonunuz varsa yanına bu rakamların değerlerini  toplayarak bir kumulatif kolonu oluşturabilirsiniz. Bence aylık veya başka dönemler için kumulatif toplam almak yerine kumulatif kolonu oluşturmak kavramı daha doğru, bu tip kumulatif kolonlar bazı satış analizleri için kullanılabiliyor.


Ben de tartismak icin degil fikir jimnastigi olsun diye devam ediyorum.

"Kumulatif kolonu" olusturmak ilk bakista dogru gibi ama degil. Dogru olmamasinin nedeni herhangi bir satirin kendisinden oncekilere bagimli olmasi. Data her zaman kesin olarak belli bir sirayla girilse ve hic duzeltme yapilmasa dogru olabilirdi. Soyle girilmis ya da o sirayla duzeltme yapilmis data dusun:

Ocak: 50 (k: 50)
Mart: 60 (k: 70)
Subat: -40 (k: 10)

Subat girdisi/duzeltmesi Mart ve sonrakileri etkiliyor. Eger o kolon var ise programcinin bunun icin kod yazmasi gerekecek. O duzeltmenin triggerlar yoluyla yapilmasi mumkun ama kullanici yuz de etkilenebileceginden cok dikkatli yazilmasi gereken bir kod olurdu.

17

Re: kümulatif toplam

foxman yazdı:

Tarık'ın sorusuna gelince.

Tarık "her ürün için her ayın sonunda stok miktarı neymiş onu görmek istiyorum" demiş. Kumulatif toplam değil aylık dönemler sonundaki "Stok durumunu" görmek istiyor.

Bu işi join veya relation kurmadan table'ı ikinci defa açmadan index ihtiyacı olmadan aşağıdaki tek bir query'ile yapması mümkün.

Query deki iif'ler sürekli çalışacağı için kod yavaş çalışır diyebilirsiniz, join veya relation kullanıldığında record pointer sürekli hem cdx içinde hemde table içinde dolaştığı içinde yavaşlıyor. Ayrıca xtab, crosstab programları yüksek sayıda kayıt içeren table'larda aşırı yavaşlayıp çuvallayabiliyor, tabi programın crosstab içindeki bir sürü kodu çalıştırmak zorunda olması da cabası.

Aşağıdaki query'nin şöyle bir avantajı daha var, eğer sonuçları ekrandan gösteren ve 12 kolon içeren bir grid'iniz varsa veya 12 kolon içeren bir raporunuz varsa onlarla oynamak zorunda kalmazsınız çünkü query sürekli 12 kolon oluşturur ayrıca NULL değer içeren kolonlar oluşmaz. Birde group by da kullanacağınız kolon sayısı query nin kapasitesi kadar çok olabiliyor.


Eger genel degil ozel queryler yapiyorsan sum(iif(...)) bir yontem. Kod bu yontemde gercekten cok yavas calisiyor (acik bir ornegi Microsoft forumlarda SQL server'in yeni pivot komutuyla ilgili olarak var. sum(iif()) yontemi korkunc yavas - saniyeler, iif() yontemi uygulamayan ise hizli 0.5 sn civarinda diye hatirliyorum - gercek sureleri orada vermistim).

"xtab, crosstab programları yüksek sayıda kayıt içeren table'larda aşırı yavaşlayıp çuvallayabiliyor, tabi programın crosstab içindeki bir sürü kodu çalıştırmak zorunda olması da cabası."

Bu tamamen yanlis bir inanis ve onyargi. Crosstab icindeki bir suru kodun calistirilmak zorunda olmasi hic birseyin gostergesi degil. Ne tek satirlik kod hizlidir diyebilirsin ne de cok satirlik kod yavas. Daha once benzeri birseyi iddia ederek UT dekilerin baslangicta denememekte israr ettikleri bir kod ornegi:

Visual Fox Pro
* laArray diye bir dizi var. Ici N tane char tipi data ile dolu.

* Birlestirip tek string isteniyor
local lcTemp, lnHandle,ix,lcString
lcTemp = sys(2015)+'.tmp'
lnHandle = fcreate(m.lcTemp)
for ix=1 to alen(laArray)
fwrite(m.lnHandle, laArray[m.ix],8192)
endfor
fclose(m.lnHandle)
lcString = FileToStr(m.lcTemp)
erase (m.lcTemp)

Sonunda denediler. Kisa kodlardan yuzlerce kez daha hizli cikti.

Cuvallamaya gelince o yazilan kodla ilgili birsey. Her kodun cuvallama sansi var. Bunu soylerken verdigim kodu denemedigini dusunuyorum (VFPnin kendi Xtab programi problemli).

Surekli 12 kolon olusturmak basit bir detay ve 2 satir ek kodla halledilir gerekirse.

NULL değer içeren kolonlari olusturmak kasitli oarak yapilan birsey, istersen olusturmazsin. 0 ile NULL'in ayni sey olmadigi durumlarda cok onemli.

Benim verdigim kodda da group by da kullanacağınız kolon sayısı query nin kapasitesi kadar çok olabiliyor.

18 Son düzenleyen, foxman (19.03.2007 17:09:25)

Re: kümulatif toplam

Tarık'ın ikinci isteği içinde bir kod gönderiyorum. Data içerisinde bulunan tüm kod ve aylar için kumulatif stok değerlerini oluşturabiliyor. Tarih aralığını birinci query de ayarlıyabilir.

Visual Fox Pro
SET DATE YMD 

Create Cursor aystok (kod c(10),tarihirs d(8),giris N(8),cikis N(8))
Insert Into aystok Values ('3516',{^2006/12/27},27,0)
Insert Into aystok Values ('3516',{^2007/01/02},0,10)
Insert Into aystok Values ('3516',{^2007/02/18},15,0)
Insert Into aystok Values ('3516',{^2007/02/28},0,4)
Insert Into aystok Values ('3516',{^2007/03/28},0,0)
FOR i=1 to 100
*    Insert Into aystok Values ('3516',CTOD(TRANSFORM(INT(rand()*2)+2006)+"/"+TRANSFORM(INT(rand()*11)+1,"@L ##")+"/"+TRANSFORM(INT(rand()*26)+1,"@L ##")),INT(rand()*5)+5,INT(rand()*5))
ENDFOR
 
SELECT kod, ;
  TRANSFORM(YEAR(tarihirs),"####") as yil,;
  TRANSFORM(MONTH(tarihirs),"@L ##") as ay,;
  SUM(giris-cikis) as stok, ;
  00000 as kumulatif ;
  FROM aystok ;
  GROUP BY 1,2,3 ;
  INTO CURSOR topStok READWRITE
 
ckodyilay=kod
pkumulatif=0
SCAN
    IF ckodyilay=kod
        REPLACE kumulatif WITH stok+pkumulatif
        pkumulatif=kumulatif
    ELSE
        ckodyilay=kod
        REPLACE kumulatif WITH stok
        pkumulatif=kumulatif
    ENDIF
ENDSCAN
 
SELECT yil,ay FROM topstok ORDER BY 1,2 INTO CURSOR periods
 
runcode=""
runcode=runcode+ "select kod ;"+chr(13)
select periods
go top
do while not eof()
    cperiod="p"+periods.yil+"_"+periods.ay
    runcode=runcode+ [,SUM(IIF(yil+ay="]+periods.yil+periods.ay+[",kumulatif,0)) as ]+cperiod +";"+CHR(13)
    select periods
    skip
enddo
runcode=runcode+ "from topstok ;"+chr(13)
runcode=runcode+ "group by kod ;"+chr(13)
runcode=runcode+ "into cursor stok_durum readwrite"+chr(13)
=execscript(runcode)
 
GO top
BROWSE LAST

19

Re: kümulatif toplam

Hmmm bu kod cok kolay kirilir. Mesela:

Visual Fox Pro
FOR i=1 to 10

  FOR j = 1 TO 12
    FOR k = 1 TO 28
      Insert Into aystok Values ('3516',;
    DATE(2007-m.i,m.j,m.k),;
    INT(rand()*5)+5,INT(rand()*5))
    ENDFOR
  endfor
ENDFOR


Yapsak olur degil mi commentli bolumde. Eger olursa bir de:

FOR i=1 to 15 ile 15 yillik almaya kalk.

20

Re: kümulatif toplam

sevgili arkadaşlar cevaplamakta geciktiğim için hepinizden özür dilerim, bir haftadır firma dışında çalışıyordum yazılan kodları deneyemedim. şimdi denemeye başladım.
çetin bey kodlar tamam yani benim istediğime cevap
ve bahsettiğiniz problem ortaya çıktı


"Kumulatif kolonu" olusturmak ilk bakista dogru gibi ama degil. Dogru olmamasinin nedeni herhangi bir satirin kendisinden oncekilere bagimli olmasi. Data her zaman kesin olarak belli bir sirayla girilse ve hic duzeltme yapilmasa dogru olabilirdi. Soyle girilmis ya da o sirayla duzeltme yapilmis data dusun:

Ocak: 50 (k: 50)
Mart: 60 (k: 70)
Subat: -40 (k: 10)

Subat girdisi/duzeltmesi Mart ve sonrakileri etkiliyor. Eger o kolon var ise programcinin bunun icin kod yazmasi gerekecek. O duzeltmenin triggerlar yoluyla yapilmasi mumkun ama kullanici yuz de etkilenebileceginden cok dikkatli yazilmasi gereken bir kod olurdu.

Kader, beyaz kağıda sütle yazılmış yazı
Elindeyse beyazdan, gel de sıyır beyazı. (NFK)

21

Re: kümulatif toplam

Çetin,
Bir kere seninki kodu kırmak değil, Foxpro'yu kırmak.
Hem sadece kumulatif kolonunun ismini km yaparak 15 yıllık dataya ulaşılıyor.
15 yıllık data kime lazım olur bilmem ama ,Daha fazlasına ihtiyaç olursa onunda çaresi var.

Ben kumulatif kolonu oluşturmaktan bahsederken hiçbiryerde
otomatik update edilmelidir demedim. Zaten hareket datasına hiçbir zaman
kumulatif kolonu konmaz. Rapor oluşturulacağı zaman bazı toplamlar alınır
ve onun yanına herzaman yeniden hesaplanan kumulatif kolonu oluşturulur.

22

Re: kümulatif toplam

Benim verdiğim Query örneği Cross Tabulate yapmak içindir hareket datasından sum yapmak için değil.
Gerçi küçük bir hareket dosyası için direkt sum yapılabilir ama büyük dosyalar sözkonusu ise bir adım önce
istenen gruba göre dikine sum yapılmalıdır. Gruba göre toplamları alınmış datayı cross tabulate sum kullanmak
(toplama amaçlı değildir) zorunludur kullanılmazsa tabulate ten sonra tek satır değil gruba ait bir matrix oluşur.
Önerdiğim query ile diğer xtab programlarının çoğunda olmayan birden fazla rakamsal kolon tabulate edilebiliyor.

23

Re: kümulatif toplam

Çetin,
Aşağıda senin söylediklerin ve test sonuçları var.

"Eger genel degil ozel queryler yapiyorsan sum(iif(...)) bir yontem. Kod bu yontemde gercekten cok yavas "
"sum(iif()) yontemi korkunc yavas"
"Bu tamamen yanlis bir inanis ve onyargi."
"Bunu soylerken verdigim kodu denemedigini dusunuyorum "

Ben aşağıdaki gibi bir datayı üretecek programı yazmak zorundaydım ve önerdiğim yöntem ile bunu başardım.
Senin karşına böyle bir data çıktığında hangi önyargılarla hareket edip 4,734,612 kayıt içeren table'ı
nasıl crosstab yapacaktın. İnatla crosstab,ctab veya diğerlerini kullanacam diye ısrar edermiydin.

24 Son düzenleyen, foxman (21.03.2007 15:16:29)

Re: kümulatif toplam

- Test Bilgisayarı.

Microsoft Windows Server 2003 Enterprise x64 Edition.
2 x Intel Xeon MP CPU
4 GB RAM

- Test Datası.

Kayıt Sayısı.                   4,734,612 Record.(hareketlerden sum edilmiş)
Crosstab Grup Kolonları.        Depo_kodu, Stok_kodu, Bolge_kodu
Crosstab Numeric Kolonları.     Miktar, YTL_tutar, USD_tutar
Crosstab Tabulate Kolonu.       Period
İstenen Kolon Sayısı            36 ay*3 kolon + 3 yıl*3 kolon = 118 Kolon

- Sonuçlar.

Query 1 İle.                    109 Saniye. (1.82 Dakika)
crosstab ile aynı olması için
Sadece Miktar kolonu tabulate
edildi.

Query 2 ile.                    284 Saniye. (4.73 Dakika)
Miktar, YTL_tutar, USD_tutar
kolonları tabulate edildi.

Crosstab ile.                   13200 Saniye.(3.67 Saat)
Sadece Miktar kolonu tabulate   Error. Subscript is outside defined range.
edilmek istendi.                Verip işlemi tamamlayamadan kesildi.
Crosstab Çuvalladı.


Visual Fox Pro
* Query 1

select Depo_kodu, Stok_kodu, Bolge_kodu ;
,SUM(IIF(period="0401",miktar,0)) as U0401 ;
,SUM(IIF(period="0402",miktar,0)) as U0402 ;
,SUM(IIF(period="0403",miktar,0)) as U0403 ;
...
...
...
,SUM(IIF(period="04Y1",miktar,0)) as U04Y1 ;
,SUM(IIF(period="05Y2",miktar,0)) as U05Y2 ;
,SUM(IIF(period="06Y3",miktar,0)) as U06Y3 ;
from data01 group by Depo_kodu, Stok_kodu, Bolge_kodu ;
into table data02 readwrite

Visual Fox Pro
* Query 2

select Depo_kodu, Stok_kodu, Bolge_kodu ;
,CAST(SUM(IIF(period="0401",miktar,0))  as numeric(7))    as U0401,CAST(SUM(IIF(period="0401",YTL_tutar,0)) as numeric(11,2)) as V0401,CAST(SUM(IIF(period="0401",USD_tutar,0))   as numeric(11,2)) as D0401 ;
,CAST(SUM(IIF(period="0402",miktar,0))  as numeric(7))    as U0402,CAST(SUM(IIF(period="0402",YTL_tutar,0)) as numeric(11,2)) as V0402,CAST(SUM(IIF(period="0402",USD_tutar,0))   as numeric(11,2)) as D0402 ;
,CAST(SUM(IIF(period="0403",miktar,0))  as numeric(7))    as U0403,CAST(SUM(IIF(period="0403",YTL_tutar,0)) as numeric(11,2)) as V0403,CAST(SUM(IIF(period="0403",USD_tutar,0))   as numeric(11,2)) as D0403 ;
...
...
...
,CAST(SUM(IIF(period="04Y1",miktar,0))  as numeric(7))    as U04Y1,CAST(SUM(IIF(period="04Y1",YTL_tutar,0)) as numeric(11,2)) as V04Y1,CAST(SUM(IIF(period="04Y1",USD_tutar,0))   as numeric(11,2)) as D04Y1 ;
,CAST(SUM(IIF(period="05Y2",miktar,0))  as numeric(7))    as U05Y2,CAST(SUM(IIF(period="05Y2",YTL_tutar,0)) as numeric(11,2)) as V05Y2,CAST(SUM(IIF(period="05Y2",USD_tutar,0))   as numeric(11,2)) as D05Y2 ;
,CAST(SUM(IIF(period="06Y3",miktar,0))  as numeric(7))    as U06Y3,CAST(SUM(IIF(period="06Y3",YTL_tutar,0)) as numeric(11,2)) as V06Y3,CAST(SUM(IIF(period="06Y3",USD_tutar,0))   as numeric(11,2)) as D06Y3 ;
from data01 group by Depo_kodu, Stok_kodu, Bolge_kodu ;
into table data02 readwrite

25

Re: kümulatif toplam

Sen haklisin.