1 Son düzenleyen, erdalyalcin (05.12.2007 20:51:14)

Konu: SET ENGINE.... 70 yapmadan

Visual Fox Pro
Select Count(talhar.ckod),talhar.ckod,talmas.cfukod From talhar;

    inner Join talmas On talhar.cmasguid =talmas.cguid ;
    GROUP By talmas.cfukod Into Cursor deneme

bu sorguyu
SET ENGINEBEHAVIOR 70 yapmadan vfp9 da nasıl yapabilirim

2

Re: SET ENGINE.... 70 yapmadan

Visual Fox Pro
Select Count(talhar.ckod),talhar.ckod,talmas.cfukod From talhar;

  inner Join talmas On talhar.cmasguid =talmas.cguid ;
  GROUP By 3 Into Cursor deneme

3

Re: SET ENGINE.... 70 yapmadan

"GROUP BY clause is invalid " hatası veriyor

4

Re: SET ENGINE.... 70 yapmadan

Select Count(talhar.ckod),talhar.ckod,talmas.cfukod From talhar;
  inner Join talmas On talhar.cmasguid =talmas.cguid ;
  GROUP By talmas.cfukod, talhar.ckod Into Cursor deneme

5

Re: SET ENGINE.... 70 yapmadan

Ya Allah aşkına çetin hocam sen
müneccimmisin nesin ya
aslında benim yapmak istediğim GROUP By talmas.cfukod, talhar.ckod iki field kullanmaktı
fuarlarda en çok istenen kartela raporu yapıyordum.
vfp8 de GROUP By da çok sayıda field kullandım. çokda ihtiyacım oldu.
ama çetrefilli yapmadan tek field ile  vfp9 nasıl yapıldığını öğrenmekti amacım.
bir gün tanışmak için izmire ziyaretine mutlaka gelicem. Yoksa gözüm açık gidecek

6

Re: SET ENGINE.... 70 yapmadan

smile hocam yakalamis benim atladigim olayi
Count(talhar.ckod) ta aggregate expressions oldugu icin onuda group by a dahil etmek gerekiyordu smile

bende simdilik set engine ile gecistirdigim icin hata verebilecek kisimlari kaciryorumm

7

Re: SET ENGINE.... 70 yapmadan

Soykan,
Aggregate olanlar gerekmiyor, olmayip ta orada olanlar gerekiyor:)

talhar.ckod, count() disinda da var.

8

Re: SET ENGINE.... 70 yapmadan

Erdal,
Aslinda muneccimlikten degil sadece VFP9 group by kurallari acisindan oyle yazdim ve geri donup istedigim bu degil demeni bekliyordum:) Istediginin ne oldugunu bilemedigimden baska sey yazmadim.
Aslinda senin group by'in 70 seklinin karsiligi biraz farkli. 70 ile sonuc benzer olsun dersen (ayni demiyorum cunku 7'de fiziksel giris sirasi etkiliyor ckod icin ne gelecegini):

Select Count(talhar.ckod),max(talhar.ckod) as ckod,talmas.cfukod From talhar;
  inner Join talmas On talhar.cmasguid =talmas.cguid ;
  GROUP By talmas.cfukod Into Cursor deneme

9

Re: SET ENGINE.... 70 yapmadan

cetinbasoz yazdı:

Soykan,
Aggregate olanlar gerekmiyor, olmayip ta orada olanlar gerekiyor:)

talhar.ckod, count() disinda da var.


hocam sunun tam mantigini aciklarsan sanirim daha kolay anlasilacak ?

ornekli olarak vfp9 ve vfp7 uyumlu orda olan olmayan olmasi gereken kismini daha iyi kavramis olacagiz.

10 Son düzenleyen, metin (06.12.2007 18:05:36)

Re: SET ENGINE.... 70 yapmadan

eğer mevzuyu doğru anladıysam ben elimden geldiğince daha basit anlatmaya çalışayım. şimdi elemanlar var kodu,adı ve primi:

select a.kod,a.adi,sum(b.prim) as topprim from cari a,primler b where a.kod=b.kod group by 1

bu vfp7 ve altında çalışır. ama üstünde çalışmaz. sebebi sql uyumluluğu. bu güzel birşey hata yapma ihtimalini azaltıyor. ama biraz daha kod yapmak gerekiyor. burda bir gruplandırma var ama adi ne toplamada ne de grup'ta yok diye hata veriyor haklı olarak.

select a.kod,a.adi,cnt(b.prim) as topprim from cari a,primler b where a.kod=b.kod group by 1,2

deyince hata vermiyor.

not: kodları denemedim. sentaks veya farketmediğim mantıksal bir hata olabilir.

Haksızlıklar karşısında susanlar, dilsiz şeytanlardır!
www.metinemre.com

11

Re: SET ENGINE.... 70 yapmadan

Soykan,
Defalarca anlattim aslinda:)

Kisaca gene anlatayim:

Visual Fox Pro
* rastgele sirayla girilmis dataya ornek

SELECT Country as ulke,City as sehir, INT(RAND()*10)*100 as MusteriSayi ;
FROM (_samples+'data\customer') ;
INTO CURSOR crsOrnek ;
NOFILTER
BROWSE

Simdi elimizde ornek olarak kullanilacak data var.

Visual Fox Pro
SET ENGINEBEHAVIOR 70

SELECT COUNT(sehir), sehir, ulke ;
FROM crsOrnek ;
GROUP BY ulke
SET ENGINEBEHAVIOR 90

Calisti ve saydi, ama neyi saydi? SQL'e bakinca Ulke basina sehirleri saymis gibi duruyor. Sonuc listesinde:

London,UK,7 (ben testdata ile arada oynuyorum belki orijinal rakamlarla tutmaz)

var. UK'yi anladik ulke gruplamasindan geldi. London nereden geldi? UK olan baska kaydimiz da yok. UK'da 7 tane London'mi var? 7 tane London ve baska hic bir sehir yok mu  orada? Tum ulkeler birer kere geciyor listede, demekki her ulkede ayni zamanda sadece birer sehir mi var? VFP7'de cevabi o rastgele secilmis bir deger o ulke sehirleri icinden (rastgele degil aslinda, fiziksel olarak cursor/tablodaki en son UK olan satirda sehir olarak London var, USA icin Seattle var vs). Bu da bir anlamda rastgele demek, cunku gruplamanin yapildigi tabloya birisi "UK, Birmingham" girerse ve biz bunu yeniden calistirirsak:

Birmingham,UK,8

ya da kimse birsey girmedi ama biz icinde order by olan bir SQL sonucu cursorden filan aliyoruz. Ya da isin icinde joinle baska tablolar var, optimizasyon nedeniyle kullanilabilecek gecici tablolarin nasil olacagini bile kestiremiyoruz. Yani sonucta fiziksel sira o degeri beliriyor. Kabaca attim tuttu gibi bir deger:)

Visual Fox Pro
SET ENGINEBEHAVIOR 70

SELECT COUNT(*), sehir, ulke ;
FROM crsOrnek ;
GROUP BY ulke
SET ENGINEBEHAVIOR 90

Sonuc ayni. Yani aslinda oraya sehir yazmakla sehirleri saymiyor. Group basina ulkenin gectigi satir sayiliyor.

Burada gercekten emin oldugumuz tek sonuc, her ulkenin kac kere gectigi.

Visual Fox Pro
SELECT COUNT(*), ulke ;

FROM crsOrnek ;
GROUP BY ulke

sehir atilinca VFP9 icin de gecerli bir SQL.

count,max,min,avg,sum,std...  bunlar aggregate fonksiyonlar. Yani bir set uzerinde yigin islemleri yapan fonksiyonlar. Group By sql'lerde bunlar serbest. Onun disinda kullanilan her alan ayni zamanda Group By icinde gecmeli.

Sehir nasil olsa atmasyon bir deger olarak geliyor VFP7'de,  alfabetik olarak ilk geleni ya da son geleni secsek de olurdu.

Visual Fox Pro
SELECT COUNT(*), MAX(sehir), ulke ;

FROM crsOrnek ;
GROUP BY ulke

Max ile gercekte isimiz yok ama illaki orada birsey istiyorsam isimi goruyor.

VFP7 ile farki anadiktan sonra baska bir group:

Visual Fox Pro
Select Count(Distinct sehir),  ulke ;

  FROM crsOrnek ;
  GROUP By ulke

Bunda sehir Count() ile ise yariyor. UK'da 2 sehirde musteri varmis. Veya:

Visual Fox Pro
Select Count(Distinct sehir), COUNT(*),  ulke ;

  FROM crsOrnek ;
  GROUP By ulke

UK'da 2 sehirde toplam 7 musteri varmis:)

TestData.dbc, OrdItems'da Quantity*Unit_price = net satis olsun. Musteri basina toplam almak istedigimizde VFP7'de bunu yapabiliyoruz (9da enginebehavior ile):

Visual Fox Pro
SET ENGINEBEHAVIOR 70

Select Cus.*, Sum(oi.Quantity * oi.Unit_price) as NetSatis ;
  FROM (_samples+'data\customer') cus ;
  left JOIN (_samples+'data\orders') ord ON cus.cust_id == ord.cust_id ;
  left JOIN (_samples+'data\orditems') oi ON ord.order_id == oi.order_id ;
  GROUP By cus.Cust_id
SET ENGINEBEHAVIOR 90

Fistik gibi, bir raporda musterilerin istedigin fieldini + netsatisi gosterecek basit bir sonuc. Burada VFP7'nin yarattigi sonuc da dogru. Rastgele hicbir deger yok. Nasil olsa Customer tablosunda belli bir cust_id'nin Company,Contact ... alanlarinda sadece bir kez geciyor (yani ALFKI ise o Alfreds Futter.. baska Alfread Futterskie... yok).

VFP9'da ise hata veriyor (sadece VFP'de degil tum ANSI SQL kullanan backendlerde).

Hatanin nedeni Cus.* dedigimize gore sonucta tum alanlari istedik. O zaman tum alanlar "Group by" da gecmeli. Ya da onceki hile gibi Cust_id disindaki alanlarda max(), min() hilesini kullanmaliyiz. Group By icinde * kullanamayiz, N tane alan, ya da select bolumnune de N tane Min(),Max() yazilmaz ki:(

Cuneyt Arkin atiliyor,
-buldum! Modify query yapariz, customer tablosunu ve tum alanlarini seceriz, SQL koduna bakip copy&paste yapariz.
-Parlak fikir... hmmm... git isine ya kim ugrasir.
-Buldum. afields() textmerge ile alanlari alip yazacak kod yapalim. Gerisi copy&paste;)
-Harika benim hazirda onu yapan kodum var... Nerde, of... ufff ... baska fikir?
-...
-Buldum... Bir SQL yapip sadece Cust_id ve Sum() alalim. Ikinci bir SQL ile sonuclari birlestirelim.
-Guzel. Aferin be calisiyor da. Cok da guzel oldu.

Da da dan... Esas olan VFP9 giriyor kapidan (bayildim yazmaktan da ondan, kafayi yemedim henuz:)
-Group by'da sizi kisitliyorum ama artik akillara ziyan SubQuery'lere izin veriyorum. Secin, ya o subquery destegi ya eski group by:)

Visual Fox Pro
Select Customer.*, tmp.NetSatis ;

  FROM (_samples+'data\customer') ;
  INNER Join ;
      (Select Cus.cust_id, Sum(oi.Quantity * oi.Unit_price) As NetSatis ;
           FROM (_samples+'data\customer') Cus ;
           left Join (_samples+'data\orders') ord On Cus.cust_id == ord.cust_id ;
           left Join (_samples+'data\orditems') oi On ord.order_id == oi.order_id ;
           GROUP By Cus.cust_id) tmp ;
  ON Customer.cust_id == tmp.cust_id

Son fikrin, tek SQL versiyonu gibi. Isin ilginci baska yollari'da var artik:)
The End

12

Re: SET ENGINE.... 70 yapmadan

daha once veresiye okumusum demekki sad dikkatli okuyunca asagidaki konulara dikkat edilince konu daha net anlasiliyor...


count,max,min,avg,sum,std...  bunlar aggregate fonksiyonlar. Yani bir set uzerinde yigin islemleri yapan fonksiyonlar. Group By sql'lerde bunlar serbest. Onun disinda kullanilan her alan ayni zamanda Group By icinde gecmeli.

Hatanin nedeni Cus.* dedigimize gore sonucta tum alanlari istedik. O zaman tum alanlar "Group by" da gecmeli. Ya da onceki hile gibi Cust_id disindaki alanlarda max(), min() hilesini kullanmaliyiz. Group By icinde * kullanamayiz, N tane alan, ya da select bolumnune de N tane Min(),Max() yazilmaz ki:(

13

Re: SET ENGINE.... 70 yapmadan

selamlar;
cetin hocam "SET ENGINEBEHAVIOR 70" ile ilgili soruyu eski forumda ilk ben sormuştum.
4-5 sayfalık bi dökümandı halen yastığımın altındadır ara ara önüme gelir okurum %50 sini anlayabilmiştim. şimdi %85 lere çıktı.
Sanırım birazdaha zamana ihtiyacım var.

Saygılar.

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

14

Re: SET ENGINE.... 70 yapmadan

o dökümanı bizimlede paylaşabilirsen sevinirim

15

Re: SET ENGINE.... 70 yapmadan

asagidaki kod VFP9 da neden hata verir ? eksik yada fazla olan nedir ? group by a 1,2 yazinca aggregate hatasi yazmayinca sql group by hatasi aliyorum

Visual Fox Pro
SET ENGINEBEHAVIOR 70 

SELECT ckodu,MAX(tarih) as tarih,aciklama FROM chnotes WHERE aciklama # [aciklama]  group by 1

olunca sorun yok sad

Visual Fox Pro
SET ENGINEBEHAVIOR 90

SELECT ckodu,MAX(tarih) as tarih,aciklama FROM chnotes WHERE aciklama # [aciklama]  group by 1

olunca hata neden ?

16

Re: SET ENGINE.... 70 yapmadan

Visual Fox Pro
SELECT ckodu,MAX(tarih) as tarih,aciklama ;

    FROM chnotes ;
    WHERE aciklama # [aciklama]  ;
    group by 1, 3


olmalı

/o---------------------o\
     www.haser.com
\o---------------------o/