Master/detail tablolarda sorgulama

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Kullanıcı avatarı
bobasturk
Kıdemli Üye
Mesajlar: 1387
Kayıt: 20 May 2004 08:39
Konum: Düzce

Master/detail tablolarda sorgulama

Mesaj gönderen bobasturk »

Merhabalar,

Sorunum hakkında arama yaparak yaklaşık 10 sayfalık dönen sonuçta yaptığım araştırmada bir çözüme ulaşamadım. Aslında yarı yarıya çözdüm desem doğru olur.

Sorunum delphi7 ve fb kullandığım çalışmamda detail tablodaki verileri ana tablodaki tarih aralığında toplatarak sonucu almak. şöyleki;

ana tablom
olayyılı-pk
olayno-pk
ınctarıhı

detail tablo
olayyılı-fk
olayno-fk
adısoyadı

Kod: Tümünü seç

select ADISOYADI, RUTBEKODU, SICILI, COUNT(*) as Toplam
from OLAYYERI1 OY, OLAYUZMAN OZ
where OY.OLAYYILI = OZ.OLAYYILI AND
OY.olayno = OZ.OLAYNO
group by RUTBEKODU, SICILI, ADISOYADI
bu kodlar ile ana tabloya bağlı olarak detail tablodaki kişilerin adsoyad bazında toplamlarını alabiliyorum. fakat yapmak istediğim vereceğim tarih aralığında bu sonucu vermesi. yukarıdaki koda between ile tarih aralığı eklediğimde sonuç boş dönüyor.

nasıl yapmalıyım ki ana tabloda bulunan ınctarıhı alanını baz alarak tarihler arası detail tabloda olayyılı ve olayno ları tutan isimlerin sayısını alabilirim.

kolay gelsin
Şefkat-u Merhamette Güneş Gibi Ol.
Başkalarının Kusurunu Örtmekte Gece Gibi Ol.
Sehavet-u Cömertlikte Akarsu Gibi Ol.
Hiddet-u Asabiyette Ölü Gibi Ol.
Tevazu-u Mahviyette Toprak Gibi Ol.
Ya Olduğun Gibi Görün Ya Göründüğün Gibi Ol.

Resim
serkan
Üye
Mesajlar: 666
Kayıt: 10 Tem 2003 12:08
Konum: bursa

Mesaj gönderen serkan »

hocam denemedim ama alt query ile yapabilirsin diye düşünüyorum. tablonu hangi alanlarla birbirlerine bağladın bilmiyorum ama.

Kod: Tümünü seç

select adisoyadi,rutbekodu,sicili,count(*) as toplam from datail_tablo where kayit_id(select kayit_id from ana_tablo where tarih1>01.01.2006 and tarih2<15.01.2006  
syntax hataları olabilir.yani ana tabloda iki tarih arasına göre arama yaptırıyorsun çıkan sonuçtaki kayit_id lere göre datail tabloyu topluyorsun.
sadece bir mantık önerisinde bulundum.
Kullanıcı avatarı
bobasturk
Kıdemli Üye
Mesajlar: 1387
Kayıt: 20 May 2004 08:39
Konum: Düzce

Mesaj gönderen bobasturk »

merhaba,

ustam doğru anlamışsınız. tarihsel alan ana tabloda detail tabloda tarihsel alan yok. tablolar olayyılı, olayno ile bir birine bağlı ve pk-fk ilişkisi var. ana tablodaki tarihsel alan arlığında detail tablodaki isimleri toplamak istiyorum.

ana tablodaki 01.01.2006 ile 31.01.2006 tarihleri arasında olayyılı ile olayno ya bağlı olan detail tablodaki isimlerin tek tek toplanması. syntax hatasını verdiğiniz örneğe dayanarak oluşturduğum sorguda bende yaşıyorum. ya select tanımıyor yada başka bir hata veriyor. benim yazdığım sql kodda tarih girmeden tüm verilerdeki isimleri tapolayıp isim ve sayıları bana döndürüyor ama bir türlü tarih aralığını koyamadım. mantık olarak aklımda ama koda dökemedim.

teşekkür ve saygı ile kolay gelsin
Şefkat-u Merhamette Güneş Gibi Ol.
Başkalarının Kusurunu Örtmekte Gece Gibi Ol.
Sehavet-u Cömertlikte Akarsu Gibi Ol.
Hiddet-u Asabiyette Ölü Gibi Ol.
Tevazu-u Mahviyette Toprak Gibi Ol.
Ya Olduğun Gibi Görün Ya Göründüğün Gibi Ol.

Resim
serkan
Üye
Mesajlar: 666
Kayıt: 10 Tem 2003 12:08
Konum: bursa

Mesaj gönderen serkan »

Kod: Tümünü seç

select ADISOYADI, RUTBEKODU, SICILI, COUNT(*) as Toplam 
from OLAYYERI1 where olayno in(select olayno from olayuzman where inctarih>'01.01.2006' and inctarih<'30.01.2006') group by ADISOYADI, RUTBEKODU, SICILI
hocam tablolar OLAYYILI ve OLAYNO alanları ile birbirine bağlı demişsiniz.Örneğin

OLAY YILI OLAY NO
2004 0001
2004 0002
2005 0002

diye bir benzerlik oluyormu yani Olay yılı farklı fakat olay no ları aynı kayıtlar varsa o biraz hataya sebep olabilir.
bir ikinciside yukardaki kodu IBExpertte çalıştırın bakalım ne hatalar verecek veya çalışacakmı.
Kullanıcı avatarı
bobasturk
Kıdemli Üye
Mesajlar: 1387
Kayıt: 20 May 2004 08:39
Konum: Düzce

Mesaj gönderen bobasturk »

Merhaba,

@Serkan ustam evet haklısınız olayno bazında benzerlik oluyor ve olacakta. fakat bizim işlemlerimiz sadece olayno ile yapılmıyor yani olayno yu kendi başına sorguda kullanmıyorum ya olayyılı+olayno yada inctarihi aralığında kullanıyorum. benzerlik göstermesi beni pek etkilemiyor.

Kod: Tümünü seç

select ADISOYADI, RUTBEKODU, SICILI, COUNT(*) as Toplam
from OLAYUZMAN where INCTARIHI in
(select inctarihi from olayyeri1 where inctarihi>'01.01.2006' and inctarihi<'30.01.2006')
group by ADISOYADI, RUTBEKODU, SICILI 
verdiğiniz kodu kendi tablolarıma uygun şekilde değiştirerek denedim fakat çalışıyormu çalışmıyormu anlamadım zira sonsuz döngüye girmiş gibi mouse şekli değişti ama sonuç vermedi neredeyse bilgisayarı kilitleyecekti.

en yukarıda belirttiğim gibi tablo yapılarım o şekil. mantık şöyle ana tabloda bulunan inctarihi alanına göre iki tarih arasında sorgulama yapacak bu sorgulama sonucu çıkan olayyılı ve olayno kayıtlı verileri detail tabloda olayyılı ve olayno ile eşleştirecek eşleştirdikten sonra içinde geçen adsoyad satırlarını toplayacak. önce ana tabloda tarihsel sorgu ve bu sorgudan çıkan kayıtlar, sonra bu kayıtların detail tabloda olayyılı ve olayno bazında çekilmesi ve son olarakta count işlemi

teşekkür ve saygılarımla kolay gelsin
Şefkat-u Merhamette Güneş Gibi Ol.
Başkalarının Kusurunu Örtmekte Gece Gibi Ol.
Sehavet-u Cömertlikte Akarsu Gibi Ol.
Hiddet-u Asabiyette Ölü Gibi Ol.
Tevazu-u Mahviyette Toprak Gibi Ol.
Ya Olduğun Gibi Görün Ya Göründüğün Gibi Ol.

Resim
serkan
Üye
Mesajlar: 666
Kayıt: 10 Tem 2003 12:08
Konum: bursa

Mesaj gönderen serkan »

hocam çok büyük değilse data dosyasını zipleyip bana mail atarsanız daha sağlıklı sonuç çıkar ortaya merak ettim hakkatten nasıl olmuyor diye.gerçi sizin kendinize uyarladığınız sorgu yanlış olmuş ama neyse..

e-posta:asnet@tekkalem.com.tr
Kullanıcı avatarı
bobasturk
Kıdemli Üye
Mesajlar: 1387
Kayıt: 20 May 2004 08:39
Konum: Düzce

Mesaj gönderen bobasturk »

@serkan ustam uyarlama yanlış olmuş diyorsunuz ama sizin verdiğiniz kodda ikinci select te olayno yu seçiyorsunuz. benim tek başına olay no ile işim yok olayyılı ve olayno beraber olmalı. ayrıca adısoyadı, rutbekodu, sicili adlı alanlar detail tablo içinde ve adısoyadı alanının toplanması gerekiyor, sizin örneğinizde from olayyeri demekle ana tablo da gibi olmuş. o yüzden uyarlama gereği duydum.

yapım tam olarak şöyle yazayım.

ana tablo OLAYYERI1

OLAYYILI-PK-integer
OLAYNO-PK-integer
INCTARIHI-date
.........

detail tablo OLAYUZMAN

IDNO-PK-integer
OLAYYILI-FK-integer
OLAYNO-FK-integer
ADISOYADI-varchar
RUTBEKODU-integer
SICILI-integer

tablo yapım tam olarak böyle. ana tabloya veri giriliyor. inceleyen uzmanlar detail tabloya (birden fazla olabileceği için bağlantılı olarak) giriliyor.

burada yapılmak istenen detail tabloda tarisel alan olmadığından belirli tarih aralığındaki kayıtları yani detail tablodaki adısoyadı alanını saymak

01.01.2006 tarihi ile 31.06.2006 tarihi arasında

ahmet 5
mehmet 10
zahmet 20
......

gibi olayı inceleyen ve detail tabloda kaydı tutulan uzman isimlerini toplamak. şimdi olayyılı ve olayno alanlarının her iki tabloda ortak olması ve pk+fk ilişki kurulmuş olmasından dolayı ana tabloda bulunan tarih aralığında elde edilen olayyılı ve olayno alanlarının eşlerini detay tabloda seçtirerer detay tablodaki adısoyadı alanını saydırmak.

gene karıştı iftara yakın olmuyor desene yırtsan olmayacak. @serkan ustam vt yi göndermek isterdim fakat içleri gerçek veriler ile dolu ve biraz sak....lı veriler o yüzden gönderemiyorum. inşeallah bu şekil çıkış yolu buluruz.

teşekkür ve saygı ile kolay gelsin hayırlı iftarlar
Şefkat-u Merhamette Güneş Gibi Ol.
Başkalarının Kusurunu Örtmekte Gece Gibi Ol.
Sehavet-u Cömertlikte Akarsu Gibi Ol.
Hiddet-u Asabiyette Ölü Gibi Ol.
Tevazu-u Mahviyette Toprak Gibi Ol.
Ya Olduğun Gibi Görün Ya Göründüğün Gibi Ol.

Resim
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Mesaj gönderen mrmarman »

Merhaba..

- Tarih içeren sorgularda, veritabanı tarih formatı göz önünde bulundurularak kullandığınız kurgu yerine aşağıda örneklediğim PARAMETRE tarzı kurguya yer verin.

- Bu sayede tarihler tam anlamıyla tarih olarak sorguya girecektir.

Kod: Tümünü seç

  With IBQuery1 do begin
    Active := False;
    SQL.Clear;
    SQL.Add( 'select ADISOYADI, RUTBEKODU, SICILI, COUNT(*) as Toplam'                );
    SQL.Add( 'from OLAYUZMAN where INCTARIHI in'                                      );
    SQL.Add( '(select inctarihi from olayyeri1 where inctarihi BETWEEN :T1 AND :T2 )' );
    SQL.Add( 'group by ADISOYADI, RUTBEKODU, SICILI'                                  );
    ParamByName( 'T1' ).DataType := ftDate; // Uses DB eklenmesi lazım gelebilir
    ParamByName( 'T1' ).Value    := StrToDate('01.01.2006');
    ParamByName( 'T2' ).DataType := ftDate;
    ParamByName( 'T2' ).Value    := StrToDate('30.01.2006');
    Active := True;
  end;
Resim
Resim ....Resim
Kullanıcı avatarı
bobasturk
Kıdemli Üye
Mesajlar: 1387
Kayıt: 20 May 2004 08:39
Konum: Düzce

Mesaj gönderen bobasturk »

Merhaba,

@muharrem ustam öğrenmek istediğim ve tırmaladığım konu bu idi. Gayet açıklayıcı örnek vermişsiniz. Teşekkür ederim.

Sorgularımda genel olarak parametre kullanıyorum. Kullanıcı iki tık fazla yapsın tarih veya aranacak kelimeyi girsin.

Yapamadığım iki ayrı tablodaki veriyi karşılaştırıp ikincil tablodaki veriyi saydırmak. Hoş sıkışınca ve beceremeyince detail tabloya ana tablodaki inctarihi verilerini update yaptım ama çalışmamda buna benzer çok detail tablo var. Yani ana tabloya bağlı dört tane detail tablo var ve bunlarda bu tür sorgulama lazım olacak.

Vermiş olduğun kodu deniyorum. İlk göze çarpan program sanki kilitlenmiş gibi görünüyor ve sonucu geç döndürüyor. Fakat sonucuna bakılırsa çalışıyor kullandığım ve geç dönsenede sonuç aldığım kodu aşağıya yazıyorum.

Teşekkür ve saygı ile kolay gelsin

Kod: Tümünü seç

var
  T1, T2:TDATE;
  begin
  With IBQuery1 do begin
    Active := False;
    SQL.Clear;
    SQL.Add( 'select ADISOYADI, RUTBEKODU, SICILI, COUNT(*) as Toplam'                );
    SQL.Add( 'from OLAYUZMAN where INCTARIHI in'                                      );
    SQL.Add( '(select inctarihi from olayyeri1 where inctarihi BETWEEN :T1 AND :T2 )' );
    SQL.Add( 'group by ADISOYADI, RUTBEKODU, SICILI'                                  );
    ParamByName( 'T1' ).AsDate:= jvdateedit1.Date;
    ParamByName( 'T2' ).AsDate :=jvdateedit2.Date;
    Active := True;
  end;
Şefkat-u Merhamette Güneş Gibi Ol.
Başkalarının Kusurunu Örtmekte Gece Gibi Ol.
Sehavet-u Cömertlikte Akarsu Gibi Ol.
Hiddet-u Asabiyette Ölü Gibi Ol.
Tevazu-u Mahviyette Toprak Gibi Ol.
Ya Olduğun Gibi Görün Ya Göründüğün Gibi Ol.

Resim
Kullanıcı avatarı
bobasturk
Kıdemli Üye
Mesajlar: 1387
Kayıt: 20 May 2004 08:39
Konum: Düzce

Mesaj gönderen bobasturk »

Sonucu döndürmesi yaklaşık bir dakikayı buluyor ustam.

kolay gelsin
Şefkat-u Merhamette Güneş Gibi Ol.
Başkalarının Kusurunu Örtmekte Gece Gibi Ol.
Sehavet-u Cömertlikte Akarsu Gibi Ol.
Hiddet-u Asabiyette Ölü Gibi Ol.
Tevazu-u Mahviyette Toprak Gibi Ol.
Ya Olduğun Gibi Görün Ya Göründüğün Gibi Ol.

Resim
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Mesaj gönderen mrmarman »

- Bu yavaşlık için açıkçası sebep görmedim. Zaten biliyor olduğunu değerlendirdiğim metodları uygulamanı şiddetle öneriyorum :wink: ... :lol:

- Dilersen bunu bir irdelemek için önce Group By satırını kaldırıp dene yüzde kaç HIZLANMA görülüyor onu test et.

- Sonra da Group By kalsın, iç select satırını kaldır. Tüm kayıtları gruplama süresini test etmiş olursun.

- Ancak bu bahsettiğim testlerle yavaşlığa neden olan kısmı tespit edebilir, onun üzerine alternatif çözümler üretmek üzere strateji belirleme işlemine başlayabilirsin.

// EK //

- Bir de veritabanı LAN içerisinde değilmi WAN'da değil ...
Resim
Resim ....Resim
aLonE CoDeR
Kıdemli Üye
Mesajlar: 1223
Kayıt: 26 Nis 2005 04:08

Mesaj gönderen aLonE CoDeR »

Selamlar.

Ben de tam olarak anlamadım bunca yazılandan sonra, sanırım sorun bende ama anladığım kadarıyla yorum yapayım; bu işlem için iki alternatif geldi aklıma, birincisi tabloları joinlemek kaydıyla sorgulamak, diğeri ise ilgili tarihleri listeleyen bir view yazarak oradan sorgulamak...

Kolay gele.
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Mesaj gönderen mrmarman »

@aLonE CoDeR

- Zaten ben de LEFT JOIN önericem ama beklemek istiyorum. Yavaşlığı JOIN ile elde edilebilecek hız kazancı vs. :o

- Ayrıca VIEW hazırlamak için gruplama ile GROUP BY'ı aynı SQL içinde vermek ile arasında hız farkı var mı ben bilmiyorum, bildiğin farklı bişey varsa açabilir misin ?
Resim
Resim ....Resim
Kullanıcı avatarı
bobasturk
Kıdemli Üye
Mesajlar: 1387
Kayıt: 20 May 2004 08:39
Konum: Düzce

Mesaj gönderen bobasturk »

Merhaba,

Ustalarım sizleri seviyorum. Gayet güzel bir şekilde bizlere bu işi ve işin püf noktalarını sabırla öğretiyorsunuz. Teşekkür ediyorum.

Ustam bu vermiş olduğun kodu ben iç select olmadan tüm kayıtları getirir vaziyette yapıyorum ve sonuç hemen dönüyor. bu işi delphi tarafında da yaptım hemen döndü ibexpert tarafında da.

Bu soruyu sormadan önce join ile yapmayı araştırdım forumda ve onun üzerine çalışma yaptım fakat uzun cümlelerim ve sorumun içinde asıl sorun olan tarih parametresini verememek oldu. tabloları birleştirebiliyordum pk+fk alanlar vasıtası ile ama tarih aralığını veremeyince sizlere danışmak istedim.

Bu gece onikiye kadar çalışacağım ve eve döndüğümde inşeallah önerileriniz doğrultusunda çözmeye çalışacağım.

detail tabloların fk alanlarını beforepost işleminde ana tablodan almasını sağlıyorum. eğer yapamazsam bu işi bu fk alanların yanına birde ana tablodan inctarihi nide aldırarak sorguyu direkt detail tabloda tarihler arasında yapacağım. aslında bu güreşten kaçmak olacak ama düşüncem bu şekil.

teşekkür ve saygı ile kolay gelsin
Şefkat-u Merhamette Güneş Gibi Ol.
Başkalarının Kusurunu Örtmekte Gece Gibi Ol.
Sehavet-u Cömertlikte Akarsu Gibi Ol.
Hiddet-u Asabiyette Ölü Gibi Ol.
Tevazu-u Mahviyette Toprak Gibi Ol.
Ya Olduğun Gibi Görün Ya Göründüğün Gibi Ol.

Resim
Kullanıcı avatarı
bobasturk
Kıdemli Üye
Mesajlar: 1387
Kayıt: 20 May 2004 08:39
Konum: Düzce

Mesaj gönderen bobasturk »

Kod: Tümünü seç

var
  T1, T2:TDATE;
  begin
  With IBQuery1 do begin
    Active := False;
    SQL.Clear;
    SQL.Add( 'select ADISOYADI, RUTBEKODU, SICILI, COUNT(*) as Toplam');
    SQL.Add( 'from OLAYUZMAN');

    SQL.Add( 'group by RUTBEKODU, SICILI, ADISOYADI'                                  );

    Active := True;
  end;
iç select kaldırıldığında sonuç tüm kayıtlarda olmak üzere hemen dönüyor.

Kod: Tümünü seç

var
  T1, T2:TDATE;
  begin
  With IBQuery1 do begin
    Active := False;
    SQL.Clear;
    SQL.Add( 'select COUNT(ADISOYADI) as Toplam'                );
    SQL.Add( 'from OLAYUZMAN where INCTARIHI in'                                      );
    SQL.Add( '(select inctarihi from olayyeri1 where inctarihi BETWEEN :T1 AND :T2 )' );
    SQL.Add( 'group by RUTBEKODU, SICILI, ADISOYADI'                                  );
    ParamByName( 'T1' ).AsDate:= jvdateedit1.Date;
    ParamByName( 'T2' ).AsDate :=jvdateedit2.Date;
    Active := True;
  end;
bu şekli ile yani select te alanları vermez isem istenen sonuç dönüyor ama bir dakika yaklaşık sürüyor.

Kod: Tümünü seç

var
  T1, T2:TDATE;
  begin
  With IBQuery1 do begin
    Active := False;
    SQL.Clear;
    SQL.Add( 'select COUNT(ADISOYADI) as Toplam'                );
    SQL.Add( 'from OLAYUZMAN where INCTARIHI in'                                      );
    SQL.Add( '(select inctarihi from olayyeri1 where inctarihi BETWEEN :T1 AND :T2 )' );

    ParamByName( 'T1' ).AsDate:= jvdateedit1.Date;
    ParamByName( 'T2' ).AsDate :=jvdateedit2.Date;
    Active := True;
  end;
bu şekil sonuç yaklaşık bir dakikada dönüyor ve toplam bütün olarak dönüyor.
Sanırım iç select işi uzatıyor. left join ile işlemi mantık olarak önce birleştirip sonra tarihler arasında sorgulama yapmak mı? ve bu join ile birleşen tabloları memtabloyamı almalıyım yoksa query zaten bunu aklında tutuyor ve kendi içinde tekrar tarihler arası sorgulayıp sonuç mu döndürüyor.

teşekkür ve saygılarımla kolay gelsin
Şefkat-u Merhamette Güneş Gibi Ol.
Başkalarının Kusurunu Örtmekte Gece Gibi Ol.
Sehavet-u Cömertlikte Akarsu Gibi Ol.
Hiddet-u Asabiyette Ölü Gibi Ol.
Tevazu-u Mahviyette Toprak Gibi Ol.
Ya Olduğun Gibi Görün Ya Göründüğün Gibi Ol.

Resim
Cevapla