[teknik]
(27) 

Sql yardımı

soluman #411663
tablo adım; egitim
tablomun içinde üç tane parametre var; eğitim adı , kişiadı ve soyadı..

mesela liderlik eğitimi alanlar için sorgu çektiğimde şöyle bişey geliyor..,


liderlik --- ahmet---yılmaz
*
*
*


ama bu ahmet yılmaz isimli şahıs başka eğitimler de almış.. ondan kafam karıştı;

sorum şu; x eğitimini alıp y eğitimini almayanları ekrana getirmek için nasıl bir sorgu çekmeliyim?

 

select * from table where egitim='x' dersen zaten sadece x eğitimini almış olanları getirir. yine de bilmek istiyorsan
select * from table where egitim='x' and egitim!='y'

bir kac yazar once

database excelden aktarma olduğundan saçma biraz, bi kişi birden çok eğitim almış durumda.. mesela select * from table where egitim='x' and egitim='y' yapıyorum bişey gelmiyor, halbuki bu iki eğitimi almış kişi var bilgilerde.

soluman

database nedir ? mysql,mssql,firebird vs.. ?

sql dosyasını gönder bakalım veya screen gönder sonuç ekranından ona göre bakalım.

bir kac yazar once

ekşiden mesaj attım

soluman

o sorgu sacma zaten, bir satirin egitim degeri hem x hem y olamaz, satir satir dusun.

select count(egitim) as a,firstname,lastname from table where (egitim='x' or egitim='y') and a=2 group by firstname,lastname;

buna benzer bir sorgu olacak ama where'in icindeki a problem yaratabilir, emin degilim. ayrica group by'a multiple kolon adini da her rdbms desteklemez. deneme yanilma yoluyla yazmak lazim simdi buradan tam cikaramadim.


edit: dur bak duzelttim, sunun calismasi lazim:

select count(egitim),firstname,lastname from table where (egitim='x' or egitim='y') group by firstname,lastname having count(egitim)=2;

@bir kac yazar once, yoo soluman oyle bir sorun belirtmemis.

samfisher

@samfisher, zaten problem where egitim='x' denildiği halde x dışındakilerin gelmesi.

Böyle bir şeyin gelmesi pek doğru/mantıklı değil bu yüzden egitim='x' and egitim!='y''de de mantık aramamak gerek :)

bir kac yazar once

@bir kac yazar once, yukaridaki editim gozden kacabilir, dogru cevabi orada verdim (diye tahmin ediyorum).

soluman'in calistirdigi
select * from table where egitim='x' and egitim='y'
ve senin onerdigin
select * from table where egitim='x' and egitim='y'

sorgularinin ikisi de anlamsiz, bunu satir satir evaluate edin, ilk sorguda bir satirdaki egitim degerinin hem x hem y olmasi mumkun olmadigindan dolayi sorgu sonucu bos donecek, senin onerdiginde de bir satirdaki egitim degeri x ise zaten y olamayacagindan butun x'ler donecek.

benim onerdigim sorguda:
select count(egitim),firstname,lastname from table where (egitim='x' or egitim='y') group by firstname,lastname having count(egitim)=2;

ise diyorum ki egitim'i x veya egitimi y olan satirlari cek, bu satirlari ad ve soyadin ayni olmas kriterine gore gruplandir ve egitim kolonunda da gelen sonuc sayisini say. eger ki bu sayi 2 ise sahis hem x hem y egitimini almistir (yani having sarti). having olmasaydi count(egitim)'i 1 olanlar sadece birinden birini almis olanlar olacakti. 0 olamaz zaten.

bu sorgu veritabaninda duplicate satir olmadigindan eminseniz dogru calisir. yoksa once tabloyu distinc ile filtrelemek gerekir, soyle bir sey olur:
select count(egitim),firstname,lastname from (select distinct * from table) t where (egitim='x' or egitim='y') group by firstname,lastname having count(egitim)=2;


SON EDIT: Kusura bakmayin, ortam karisinca soluman'in ikinci post'undaki soruya cevap vermis, ana soruyu atlamisim. dogru cevap soyle olsa gerek:

select distinct firstname,lastname from table where egitim='x' MINUS select distinct forstname,lastname from table where egitim='y';

samfisher

select kişi
from table
where egitim = x
group by kişi

kta

@samfisher,
select * from table where egitim='x' and egitim!='y'

benim verdiğim egitim!='y'

yani select * from table where egitim='x' iken x dışında sonuç getirmesi zaten mantıksız bu mantıksızlıkta ben de diyorum ki egitim!='y' diyerek y sonuçlarını engellemeye çalış. Ben hem x, hem y olanları nasıl çekeceğini söylemiyorum. Sadece x olanları nasıl çekeceğini söylemeye çalışıyorum.

bir kac yazar once

@kta senin sorgunda ornegin x egitimi ve z egitimi almis kisiler donmuyor. egitimin x ve y gibi iki olasiligi oldugunu varsaymissin.

@bir kac yazar once az once yazdigim da dogru sorunun cevabi degilmis, son kez editledim, bu defa oldu gibi. :)

samfisher

@samfisher, abi sen olayın komut yönündesin ama ortada çok farklı bir durum var diye düşünüyorum.

selec.... where egitim='x' denildiğinde zaten x dışındaki sonuçları getirmemesi gerekiyor. Bu yüzden minus veya egitim!='y' ile düzeleceğini sanmıyorum. O yüzden arkadaştan ekran görüntüsü veya db'yi istedim.

bir kac yazar once

Abi benim tam kafa gitti ya, senin editli kod çalışmadı..

database şöyle;

eğitimadı adi soyadi
x ahmet yılmaz
y ahmet yılmaz
z ali veli
x ali veli

böyle böyle 3 bin tane satır var, bir kişi onlarca eğitim almış durumda.. ben istiyorumki x eğitimini alıp z yi almayanları sorgulayım.. yani x eğitimi alanlar ahmet ve ali ama x i alıp z yi almayanlar sadece ahmet... yani sadece ahmet gelecek şekilde olsun sorgum..

soluman

hayir, soyle bir tablo dusun

egitim____ad_______soyad

x_________alican___tosun
y_________alican___tosun
x_________ahmet____ozturk
z_________ahmet____ozturk
y_________mehmet___aslan
z_________mehmet___aslan
x_________ali______atay

(isim sallamak ne zormus arkadas)

neyse, bizim sorgumuzun sonucunda x almis y almamis kisilerin donmesi gerekiyor, yani ahmet ozturk ve ali atay'i istiyoruz.
sorgunun
select distinct firstname,lastname from table where egitim='x'
kismi sonucunda donen sonuc
ad______soyad
alican__tosun
ahmet___ozturk
ali_____atay

MINUS'tan sonraki
select distinct forstname,lastname from table where egitim='y'
kisminda donen sonuc:
ad______soyad
alican__tosun
mehmet__aslan

ilk sonuc FARK ikici sonuc, yani ilkinden ikincide de olan sonuclari cikariyoruz ki bu sonuc sadece alican tosun, elimizde su kaliyor:
ad______soyad
ahmet___ozturk
ali_____atay

sanirim oldukca acik oldu.

edit: soluman senin soruna da cevap vermis oluyorum. tam olarak calistiracagin sorgu su:
select adi,soyadi from TABLONUNADI where egitimadi='x' MINUS select adi,soyadi from TABLONUNADI where egitimadi='z';

ama eger tablonda duplicate satirlar, yani birbirinin tamamen aynisi olan satirlar varsa distinct'leri de koyman gerekir. olmadigini biliyorsan gerek yok.

samfisher

kod çok mantıklı ama minus ta hata veriyor , bu şekilde kulanıldığına emin misin?

soluman

select name from table t1 where egitim='x' and not exists(select name from table t2 where t1.name=t2.name and t2.egitim!='x') group by t1.name

sorgusu ile sadece tek eğitim almış olanları bulabilirsin.

edit: samfisher'in yazdığı da çalışıyor olması lazım.

bir kac yazar once

minus yerine except yazdım geldi bişeyler, yarın kontrol edecem doğru mu yanlış mı diye çok teşekkürler hepinize:)

soluman

tabi ki, www.techonthenet.com

MS Sql Server kullaniyorsan MINUS keyword'u yerine EXCEPT var imis. Bir de onu dene bakalim.

budut: gec kalmisim :)

samfisher

oo canavar gibi çalışıyor valla:)

@bir kac yazar önce ; yazdığın son koduda not aldım, ama tek eğitim alan kimse yok sistemde farklı alternatif kodlarla güncel tutabilirsiniz başlığı :)

soluman

select name from table t1 where egitim='x' and not exists(select name from table t2 where t1.name=t2.name and t2.egitim!='x') group by t1.name

and t2.egitim!='x' kısmında x yerine y yazarsan:

x eğitimi almış, y eğitimi almamış kişileri bulursun. kodun amacı şu;

önce x eğitimi almış herkesi buluyor, daha sonra parantez içinde belirttiğin eğitimi almamış kişileri buluyor ikisi arasındaki farkı getiriyor.

bir kac yazar once

@bir kac yazar once,
tablolari olusturdum, senin sorgunu denedim, benim verdigim ornekte sadece ali atay'i donduruyor senin sorgun.

dedigin gibi t2.egitim!='x' 'teki x yerine y yazdim, calistirdim, bos dondu.

bir de unlemi kaldirdim, yani t2.egitim='y' oldu not exists'in icindeki kisim, o durumda da ahmet ozturk ile ali atay geldi.

3 durumda da sikinti var.

samfisher

hacı üşenmedim tablo oluşturdum;

resimlere bakarak anlayabilirsin.

select adi from a a1 where a1.egitim='x' and not exists(select * from a a2 where a1.adi=a2.adi and a2.egitim='z') group by a1.adi

Bu kod ile x eğitimini almış, z eğitimini almamış kişileri bulabilirsin.

img23.imageshack.us
img59.imageshack.us

ok'midir ?

bir kac yazar once

@bir kac yazar once senin sorgunla Z eğitimi almamış kisileri bulursun. ilk sorguya x eğitim şartını koymalısın.

select adi from a a1 where a1.egitim='x' and not exists(select * from a a2 where a1.adi=a2.adi and a2.egitim='z') group by a1.adi

€xpolerer

@€xpolerer, aynen yukarıda doğrusunu yazmışım ama aşağıda çalıştırırken and a1.egitim='x' 'i eklemeyi unutmuşum. Gece 5'de olur o kadar :)

kodu editledim tekrar.

bir kac yazar once

@ bir kac yazar önce, hocam emeğin için teşekkürler öncelikle ama senin kodu benim database e uyarlıyamıyorum mesela a1 a2 dediğin şeyler tablo adı mı? öyleyse bende sadece bir tablo var..

şöyle söylim, tablo adı = egitim

taablonun içindeki parametreler; egitim adi, calisan adi , calisan soyadi

bu parametreleri kullanarak senin kodu güncelleyebilirsen sevinirim

soluman

@soluman, a1,a2 alias onları ellememen gerekiyor.

benim tablo adı da egitim tek değiştirmen gereken yer adi alanı.

a1.adi=a2.adi kısmı var ya oraya calışan adı'nı yazacaksın

bir kac yazar once

abi ben zaten x eğitimini alıp y eğitimini almayanların listesine select çekmek istiyorum, kişinin adını yazamam ki istediğim o zaten.

soluman

@soluman, abi adını yaz demiyorum. kolon ismini yazacaksın demeye çalışıyorum.

çalışanların saklandığı kolon ismi ne calisan_adi diyelim

select calisan_adi from a a1 where a1.egitim='x' and not exists(select * from a a2 where a1.adi=a2.adi and a2.egitim='y') group by a1.calisan_adi

yapacaksın. mevzu bu.

bir kac yazar once
1

mobil görünümden çık