Toplam alma hakkında bir soru... (Sum)

MS SQL Server veritabanı ve SQL komutlarıyla ilgli sorularınızı sorabilirsiniz. Delphi tarafındaki sorularınızı lütfen Programlama forumunda sorunuz.
Cevapla
aycen
Üye
Mesajlar: 20
Kayıt: 17 Mar 2008 03:08

Toplam alma hakkında bir soru... (Sum)

Mesaj gönderen aycen »

s.a.

Bir muhasebe programı geliştiriyorum. Muhasebe ile ilgilenenler bilir raporlardan en önemlisi "mizan" dır.
2 table var .
HPL_TBL hesap planı (6000 kayıt var)
MHS_TBL hesap haraketleri (100000 kayıt var)

nasıl yapmalıyım ben aşağıdaki şekilde yaptım fakat kayıt fazla oluduğunda veya bir yerde hata yapıyorum. çok uzun sürüyor (30 dk fazla)

Kod: Tümünü seç

SELECT     HSP_KOD,
                          (SELECT     SUM(MHS_B) AS Expr1
                            FROM          MHS_TBL AS T2
                            WHERE      (LEFT(MHS_KOD, LEN(T1.HSP_KOD)) = T1.HSP_KOD)) AS BORC,
                          (SELECT     SUM(MHS_A) AS Expr1
                            FROM          MHS_TBL AS T3
                            WHERE      (LEFT(MHS_KOD, LEN(T1.HSP_KOD)) = T1.HSP_KOD)) AS ALACAK
FROM         dbo.HPL_TBL AS T1

bu konuda bana yardımcı olacak arkadaşlar varsa şimdiden teşekkürler....
aycen
Üye
Mesajlar: 20
Kayıt: 17 Mar 2008 03:08

Re: Toplam alma hakkında bir soru... (Sum)

Mesaj gönderen aycen »

Bu arada hesap planı şu şekilde;

100
100.01
100.01.100
100.01.100.1001
100.01.200
100.01.200.1001
200
200.01
200.01.100
200.01.100.500
...
...
...
Hakan Can
Üye
Mesajlar: 634
Kayıt: 04 Mar 2005 04:27
Konum: Ankara

Re: Toplam alma hakkında bir soru... (Sum)

Mesaj gönderen Hakan Can »

Şu query'yi test edebilir misin?

Kod: Tümünü seç

SELECT
  T1.HSP_KOD,
  SUM(T2.MHS_B) AS BORC,
  SUM(T2.MHS_A) AS ALACAK
FROM HPL_TBL T1
  LEFT JOIN MHS_TBL T2 ON T2.MHS_KOD LIKE T1.HSP_KOD + '%'
GROUP BY T1.HSP_KOD
aycen
Üye
Mesajlar: 20
Kayıt: 17 Mar 2008 03:08

Re: Toplam alma hakkında bir soru... (Sum)

Mesaj gönderen aycen »

Kod: Tümünü seç

  with CSM_Data.MZN_ADODataSet do begin
    Active := false;
    CommandText := 'select  T1.HSP_KOD,T1.HSP_AD,T1.HSP_KBR,T1.HSP_LVL,' +
                            'sum(CASE WHEN T2.MHS_BA=''B'' THEN T2.MHS_TUTAR ELSE 0 END) as brc, ' +
                            'sum(CASE WHEN T2.MHS_BA=''A'' THEN T2.MHS_TUTAR ELSE 0 END) as alc ' +
                            'from CSM_' + Firma + '_' + Donem + '_HPL_TBL AS T1 LEFT OUTER JOIN ' +
                            'CSM_' + Firma + '_' + Donem + '_MHS_TBL AS T2 ON T2.MHS_KOD LIKE T1.HSP_KOD + ''%'' ' +
                            'where T1.HSP_KOD between :KOD1 and :KOD2 ' +
                            'Group by T1.HSP_KOD,T1.HSP_AD,T1.HSP_KBR,T1.HSP_LVL ' +
                            'order by T1.HSP_KOD';
    Parameters.ParamByName('KOD1').DataType := ftString;
    Parameters.ParamByName('KOD1').Value := '100';
    Parameters.ParamByName('KOD2').DataType := ftString;
    Parameters.ParamByName('KOD2').Value := '999';
    Active := True;
  end;
son hali bu şekilde ... üstad senin verdiğin query yi denedim . yeterli gelmiyor. burda bir mantık hatası mı yapıyorum acaba bu mizanı almak bukadar zor olmasa gerek...

işlemin bitmesine ne kadar kaldığını nasıl gösteririz ? progresbar gibi birşey nasıl yaparız.
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3081
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Re: Toplam alma hakkında bir soru... (Sum)

Mesaj gönderen sabanakman »

Çok fazla miktardaki kaydı hesaplatmak bu kadar zordur işte. Benim önerim çapraz eşleşmeyi azaltman olacak ve bu yol için sanal tablo kullanmayı önereceğim. Mesela

Kod: Tümünü seç

if (OBJECT_ID('tempdb..#mizan') is null then drop table #mizan)--sanal tablo varsa sil
select HSP_KOD, HSP_AD,cast(0 as float) Borc, cast(0 as float) as Alacak into #mizan from dbo.HPL_TBL AS --sanal hesaplanmamış mizan tablosu oluştur
update #mizan set Borc=Borc+MHS_Borc, Alacak=Alacak+MHS_Alacak from (select MHS_Kod,sum(MHS_B) as MHS_Borc,sum(MHS_A) as MHS_Alacak) as Toplam where CharIndex(HSP_KOD,MHS_Kod)=1 group by MHS_Kod
select * from #mizan order by HSP_KOD
gibi bir sorguyla işlemde dikkate alınan kayıt eşleşme sayılarını iyice azaltmanı öneririm. Hatta bu sorgu da işini görmezse son update sorgusu da çok işlem yapabileceğinden where şartını HSP_KOD=MHS_Kod şeklinde verip, daha sonra açılan tabloda alınamayan toplamları kodla aldırabilirsin. Aksi halde bu kadar çok miktardaki kayıtları çapraz ilişkilendirmede kullanmak başa bela olacaktır.
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
aycen
Üye
Mesajlar: 20
Kayıt: 17 Mar 2008 03:08

Re: Toplam alma hakkında bir soru... (Sum)

Mesaj gönderen aycen »

Kod: Tümünü seç

  with CSM_Data.MZN_ADODataSet do begin
    Active := false;
    CommandText := 'select  T1.HSP_KOD,' +
                            'sum(CASE WHEN T2.MHS_BA=''B'' THEN T2.MHS_TUTAR ELSE 0 END) as Brc, ' +
                            'sum(CASE WHEN T2.MHS_BA=''A'' THEN T2.MHS_TUTAR ELSE 0 END) as Alc ' +
                            'from CSM_' + Firma + '_' + Donem + '_HPL_TBL AS T1 LEFT OUTER JOIN ' +
                            'CSM_' + Firma + '_' + Donem + '_MHS_TBL AS T2 ON T2.MHS_KOD = T1.HSP_KOD ' +
                            'where (T2.MHS_TRH BETWEEN :TRH1 AND :TRH2) AND (T1.HSP_KOD between :KOD1 and :KOD2) ' +
                            'Group by T1.HSP_KOD ' ;
   end;
   MZN_ADODataSet.Parameters.ParamByName('KOD1').DataType := ftString;
   MZN_ADODataSet.Parameters.ParamByName('KOD1').Value := B_KOD;
   MZN_ADODataSet.Parameters.ParamByName('KOD2').DataType := ftString;
   MZN_ADODataSet.Parameters.ParamByName('KOD2').Value := S_KOD;
   MZN_ADODataSet.Parameters.ParamByName('TRH1').DataType := ftDate;
   MZN_ADODataSet.Parameters.ParamByName('TRH1').Value :=  DateToStr(B_TRH_DateTimePicker.Date);
   MZN_ADODataSet.Parameters.ParamByName('TRH2').DataType := ftDate;
   MZN_ADODataSet.Parameters.ParamByName('TRH2').Value :=  DateToStr(S_TRH_DateTimePicker.Date);
   MZN_ADODataSet.Active := true;

   MZN_kbmMemTable.FieldDefs := HPL_ADODataSet.FieldDefs;
   MZN_kbmMemTable.IndexDefs := HPL_ADODataSet.IndexDefs;
   MZN_kbmMemTable.LoadFromDataSet(HPL_ADODataSet,[]);

    MZN_kbmMemTable.Filtered := False;
    MZN_kbmMemTable.Filter := '(HSP_KOD>= ' + QuotedStr(B_KOD) + ' and ' +
                               'HSP_KOD<= ' + QuotedStr(S_KOD) + ' )';
    MZN_kbmMemTable.Filtered := True;

    MZN_ProgressBar.Max := MZN_ADODataSet.RecordCount;

    with MZN_ADODataSet do begin
      First;
      while not Eof do begin
        BKY_EKLE(FieldByName('HSP_KOD').AsString,FieldByName('Brc').AsFloat,FieldByName('Alc').AsFloat);
        Next;
        MZN_ProgressBar.Position := MZN_ADODataSet.RecNo;
      end;
    end;

Kod: Tümünü seç

procedure BKY_EKLE(HSP : string ; Borc, Alacak: Double);
var
  AHSP : string;
begin
  with CSM_Data do begin
    if MZN_kbmMemTable.Locate('HSP_KOD',HSP,[]) then begin
      AHSP := MZN_kbmMemTable.FieldByName('HSP_AKOD').AsString;
      MZN_kbmMemTable.Edit;
      MZN_kbmMemTable.FieldByName('HSP_B').AsFloat := Borc;
      MZN_kbmMemTable.FieldByName('HSP_A').AsFloat := Alacak;
      MZN_kbmMemTable.Post;
    end;
    while AHSP <> '' do begin
      if MZN_kbmMemTable.Locate('HSP_KOD',AHSP,[]) then begin
        MZN_kbmMemTable.Edit;
        MZN_kbmMemTable.FieldByName('HSP_B').AsFloat := MZN_kbmMemTable.FieldByName('HSP_B').AsFloat + Borc;
        MZN_kbmMemTable.FieldByName('HSP_A').AsFloat := MZN_kbmMemTable.FieldByName('HSP_A').AsFloat + Alacak;
        MZN_kbmMemTable.Post;
        AHSP := MZN_kbmMemTable.FieldByName('HSP_AKOD').AsString;
      end;
    end;
  end;
end;
Son hali bu şekide yaptım. Süre bana yeterli geldi. teşekkür ederim.
Bu kodu daha hızlandırmak için önerisi olan varsa alabilirim.
Cevapla