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)
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....
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
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.
Ç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
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. - .
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.