SQL Yapilari
ve Tablodan Istenilen Verinin Elde Edilmesi
Mysql istemcinizi acin ve bu bolumde yapacagimiz SELECT sorgu
yapilarini ogrenin.Bir cok onemli yapi bu makalede orneklerle
anlatilacaktir.Ilk olarak SELECT SQL yapisi ile ilgili bir
kac hatirlatma yapmak istiyorum.Birincisi bu SQL komutu bir
veritabani tablosuna ve/veya bir veritabanina ihtiyac duymaz.SELECT
komutu verinin dondurulmesi icin kullanilir.Unutmayin burada
yapacagimiz ornekler tamamiyle PHP fonksiyonlari yardimiyla
da sunucu uzerinde uygulanabilir.(Bunun nasil yapildigini
genis olarak onceki yazilarimizda acikladik.)
Biz simdilik MySQL istemcisini sorgularimizi gerceklestirmek
icin kullaniyoruz ama sonucta onemli olan sorgu yapisinin
kendisi.Nerede ve hangi teknigi kullanarak onu veritabani
uzerinde uyguladiginiz degil :)
MySQL Veritabani Sunucusu cok fazla yapisal fonksiyon icerir.Buna
bir ornek vermek gerekirse, saatinizi evde unuttugunuzu farzedin.Bunu
MySQL sunucundan nasil ogrenebiliriz?
Iste cevap :
mysql> SELECT now();
+---------------------+
| now() |
+---------------------+
| 2001-10-01 15:34:48 |
+---------------------+
1 row in set (0.11 sec)
Yukaridaki ornekte goruldugu gibi now() hazir fonksiyonu
ile sunucu uzerindeki zaman verisini dondurmus oldum.now
() fonksiyonu o andaki gecerli zamani dondurur.Eger gecerli
tarih ve gecerli saati ayri ayri dondurmek istiyorsaniz curdate
() ve curtime() fonksiyonlarini kullanabilirsiniz
:
Tarih :
mysql> SELECT curdate();
+------------+
| curdate() |
+------------+
| 2001-10-01 |
+------------+
1 row in set (0.00 sec)
Zaman :
mysql> SELECT curtime();
+-----------+
| curtime() |
+-----------+
| 15:38:35 |
+-----------+
1 row in set (0.00 sec)
veya beraberce :
mysql> SELECT curdate(),curtime();
+------------+-----------+
| curdate() | curtime() |
+------------+-----------+
| 2001-10-01 | 15:39:36 |
+------------+-----------+
1 row in set (0.00 sec)
MySQL hazir fonksiyonlari hemen hemen PHP ile ayni sekilde
calisir.Bazi degisiklikler elbette vardir.Ornegin PHP'deki
substr () fonksiyonu yerine MySQL'de hazir fonksiyon
olarak substring () kullanilir.PHP sifirdan (0) saymaya
baslarken ornegin MySQL hazir fonksiyonu birden (1) baslayarak
sayar.Bir ornek vermek gerekirse :
mysql> SELECT substring('test',1,1);
+-----------------------+
| substring('test',1,1) |
+-----------------------+
| t |
+-----------------------+
1 row in set (0.06 sec)
Bu islemin PHP'deki esiti asagidaki gibidir :
$degisken_parcasi = substr('test',0,1);
Bir tablo alanindaki veriyi dondurmek
Simdiye kadar bir tablodan veriyi dondurmeyi gorduk.Peki yanlizca
tablonun bir alanindaki veriyi dondurmek istersek ne yapabiliriz?
Bunun icin asagidaki gibi bir SQL sorgusu hazirlayip veritabani
uzerinde uygulamak yeterlidir :
mysql> SELECT kullaniciadi FROM kullanicilar;
+--------------+
| kullaniciadi |
+--------------+
| ahmet |
| hikmet |
| memis |
| oktay |
| serkan |
| tayfun |
+--------------+
6 rows in set (0.22 sec)
Iki farkli alanaki veriyi dondurmek icin, alanlari virgul
(,) ile ayirmak gereklidir :
mysql> SELECT kullaniciadi,gercekadi FROM kullanicilar;
+--------------+---------------------+
| kullaniciadi | gercekadi |
+--------------+---------------------+
| serkan | Serkan Hadi Ceylani |
| oktay | Oktay Altunergil |
| tayfun | Tayfun Ulu |
| memis | Memis Cetinkaya |
| hikmet | Hikmet Gumus |
| ahmet | Ahmet Yazici |
+--------------+---------------------+
6 rows in set (0.06 sec)
Tablodaki butun alanlardaki veriyi dondurmek icin (*) yildiz
isareti kullanilmalidir :
mysql> SELECT * FROM erisim;
+-------------------------+--------------+---------------+----------------+
| sayfa | kullaniciadi | ziyaretsayisi | erisimtarihi |
+-------------------------+--------------+---------------+----------------+
| /headbangers/index.html | serkan | 9 | 19990921123155 |
| /index.html | oktay | 2 | 20000511161120 |
| /index.html | tayfun | 8 | 20000522163110 |
| /php/myscript.php | tayfun | 5 | 20000713220144 |
| /php/myscript.php | memis | 1 | 20000826071502 |
| /who.html | serkan | 6 | 19991123172000 |
+-------------------------+--------------+---------------+----------------+
6 rows in set (0.11 sec)
Donen Veriyi Belirli Limitlere Bolmek
LIMIT ve WHERE anahtar kelimeleri ile donen sonuc belirli
limitlerde istenebilir.Boylece ornegin sifirdan baslayarak
ilk iki sonucun dondurulmesini asagidkai gibi bir sorgu ile
gerceklestirebilirsiniz :
mysql> SELECT kullaniciadi,gercekadi FROM kullanicilar
LIMIT 0,2;
+--------------+---------------------+
| kullaniciadi | gercekadi |
+--------------+---------------------+
| serkan | Serkan Hadi Ceylani |
| oktay | Oktay Altunergil |
+--------------+---------------------+
2 rows in set (0.00 sec)
Aslinda sorgu icinde (eger tablonun basindan itibaren ilk
iki sonucu istiyorsaniz) sifirin kullanilmasina gerek yoktur.Asagidaki
gibi bir sorgu da tamamen ayni isi gorecektir.Boylece siz
eger "0" notasyonunu yazmaz iseniz o kendiliginde baslangic
degerini sifir alacaktir :
mysql> SELECT kullaniciadi,gercekadi FROM kullanicilar
LIMIT 2;
+--------------+---------------------+
| kullaniciadi | gercekadi |
+--------------+---------------------+
| serkan | Serkan Hadi Ceylani |
| oktay | Oktay Altunergil |
+--------------+---------------------+
2 rows in set (0.00 sec)
Baska bir dusunce ile yanlizca "Turkiye"de yasayan kullanicilarin
secilmesi (secimin biizm istegime gore limitlenmesi) saglanabilir
: Burada WHERE anahtar kelimesi kullanilarak sorgu hazirlaniyor.
mysql> SELECT kullaniciadi,gercekadi FROM kullanicilar
WHERE milliyeti = 'Turkiye';
+--------------+--------------+
| kullaniciadi | gercekadi |
+--------------+--------------+
| hikmet | Hikmet Gumus |
+--------------+--------------+
1 row in set (0.05 sec)
Operatorler
Sorgularda esitlik,buyukluk vb. istekleri saglayabilmek icin
operatorler vardir.Simdi asagiya bu operatorlerin hepsini
yaziyorum :
= (Esittir)
!= veya <> (Esit Degildir)
< (Bundan Kucuk)
> (Bundan Buyuk)
<= (Bundan Kucuk veya Esit)
>= (Bundan Buyuk veya Esit)
NULL degeri karsilatirilamaz.Yanlizca NULL'mu degilmi diye
bakilabilir.NULL degeri = veya != gibi operatorlerle karsilastirmayiniz.Bunun
yerine IS NULL veya IS NOT NULL notasyonlari ile alandaki
degerin NULL olup olmadigina bakiniz.
Simdi de LIMIT ve WHERE anahtar kelimelerini beraber kullanarak
bir sorgu yaratalim.Bu sorgumuzda "Amerika Birlesik Devletlerinde"
yasayan ilk kullanicimizi ogrenmek isteyelim :
mysql> SELECT kullaniciadi,gercekadi FROM kullanicilar
WHERE milliyeti = 'Amerik
a Birlesik Devletleri' LIMIT 1;
+--------------+---------------------+
| kullaniciadi | gercekadi |
+--------------+---------------------+
| serkan | Serkan Hadi Ceylani |
+--------------+---------------------+
1 row in set (0.00 sec)
Onemli NOT : LIMIT anahtar kelimesi her zaman en sonda
yer alir
Coklu secimler AND ve OR mantiksal opratorleri ile yapilabilir
: (Ingilizce AND "ve" anlamina OR ise "veya" anlamina gelmektedir.)
mysql> SELECT kullanicinumarasi,kullaniciadi,milliyeti
FROM kullanicilar WHERE m
illiyeti = 'Ingiltere' OR milliyeti = 'Amerika Birlesik Devletleri'
AND kullanic
inumarasi < 5;
+-------------------+--------------+-----------------------------+
| kullanicinumarasi | kullaniciadi | milliyeti |
+-------------------+--------------+-----------------------------+
| 1 | serkan | Amerika Birlesik Devletleri |
| 2 | oktay | Amerika Birlesik Devletleri |
| 4 | memis | Amerika Birlesik Devletleri |
| 6 | ahmet | Ingiltere |
+-------------------+--------------+-----------------------------+
4 rows in set (0.06 sec)
Yukarida cok onemli bir durum soz konusudur.Buraya iyi dikkat
etmenizi oneriyorum.Sorguda goruldugu gibi "kullanicinumarasi"
5'den kucuk olan kayitlar istenmektedir.Yanliz dikkat ederseniz
sonuc setinde halen 6 kullanici numarasina sahip bir kullanici
bulunmaktadir.Sizce ne oldu dersiniz?MySQL hata mi yapiyor?
Hayir.Biz sorguyu hazirlarken bazi seyleri goz onunden bulundurmaliyiz.Bunlaradan
ilki sorgu devam ederken daha "kullanicinumarasi < 5" ifadesine
gelinmeden ilk sarta gore (yani 'Ingiltere') zaten MySQL tablodan
veri secimini yapmistir.Bu nedenle "kullanicinumarasi <
5" sarti yanlizca (milliyeti='Amerika Birlesik devletleri')
satirina uygulanir.yani secilmis bir veriyi diger sart bunu
saglamiyor diye geri alamazsiniz...
Eger yukaridaki gibi bir durumun olusmasini istemiyorsaniz
"parantezlerle" sorgunuza bir anlama katabilirsiniz :
mysql> SELECT kullanicinumarasi,kullaniciadi,milliyeti
FROM kullanicilar WHERE (
milliyeti = 'Ingiltere' OR milliyeti = 'Amerika Birlesik Devletleri')
AND kullan
icinumarasi < 5;
+-------------------+--------------+-----------------------------+
| kullanicinumarasi | kullaniciadi | milliyeti |
+-------------------+--------------+-----------------------------+
| 1 | serkan | Amerika Birlesik Devletleri |
| 2 | oktay | Amerika Birlesik Devletleri |
| 4 | memis | Amerika Birlesik Devletleri |
+-------------------+--------------+-----------------------------+
3 rows in set (0.00 sec)
Donen Sonuclari Siralamak
Donen sonuclari belirli bir alana gore siralamak istiyorsaniz
ORDER BY anahtar kelimesini kullanabilirsiniz :
mysql> SELECT kullanicinumarasi,kullaniciadi,milliyeti
FROM kullanicilar WHERE k
ullanicinumarasi < 5 ORDER BY kullaniciadi;
+-------------------+--------------+-----------------------------+
| kullanicinumarasi | kullaniciadi | milliyeti |
+-------------------+--------------+-----------------------------+
| 4 | memis | Amerika Birlesik Devletleri |
| 2 | oktay | Amerika Birlesik Devletleri |
| 1 | serkan | Amerika Birlesik Devletleri |
| 3 | tayfun | Turkiye Cumhuriyeti |
+-------------------+--------------+-----------------------------+
4 rows in set (0.05 sec)
Onemli NOT : ORDER BY ile siralama yapilirken ASCII tablosuna
gore yapilir.Bu nedenle kucuk harfler,buyuk harflerden sonra
yer alir.
ORDER BY belirli bir alana gore siralamayi ongorulen olarak
bastan sona dogru (Anahtar Kelime ASC kullanilarak) yapar.(Veya
alfabede, alfabenin basindan sonuna dogru)Eger ters bir siralama
yapmak istiyorsaniz DESC anahtar kelimesini kullanabilirsiniz.
mysql> SELECT kullaniciadi FROM kullanicilar ORDER BY kullaniciadi
DESC;
+--------------+
| kullaniciadi |
+--------------+
| tayfun |
| serkan |
| oktay |
| memis |
| hikmet |
| ahmet |
+--------------+
6 rows in set (0.22 sec)
Birden fazla alana gore siralama ise su sekilde yapilabilir
:
mysql> SELECT kullaniciadi,gercekadi,milliyeti FROM kullanicilar
WHERE milliyeti
= 'Ingiltere' OR milliyeti = 'Amerika Birlesik Devletleri'
ORDER BY milliyeti,k
ullaniciadi DESC;
+--------------+---------------------+-----------------------------+
| kullaniciadi | gercekadi | milliyeti |
+--------------+---------------------+-----------------------------+
| serkan | Serkan Hadi Ceylani | Amerika Birlesik Devletleri
|
| oktay | Oktay Altunergil | Amerika Birlesik Devletleri |
| memis | Memis Cetinkaya | Amerika Birlesik Devletleri |
| ahmet | Ahmet Yazici | Ingiltere |
+--------------+---------------------+-----------------------------+
4 rows in set (0.22 sec)
Karekter Eslesmesi
LIKE ve NOT LIKE operatorleri ile veri uzerinde istenilen
karekterlerin bulunup bulunmadigi kontrol edilebilir.Bu operatorler
daha cok, web sitelerinin arama bolumlerinde kullanilmaktadir.
% isareti ile
verinin herhangi bir yerindeki eslesme (bos karekterler de
dahil) daha cok DOS veya UNIX komut satirindaki * ile ayni
gorevde,
_ isareti ile
tek bir karekter (daha cok DOS ve UNIX komut satirindaki ?
ile ayni gorevde)
Ornegin "kullanicilar" tablosundaki "eposta" isimli alanda
"turk-php.com" domain adina sahip eposta adreslerini listelemek
istiyorum :
mysql> SELECT kullaniciadi,gercekadi,milliyeti FROM kullanicilar
WHERE eposta LI
KE '%turk-php.com' ORDER BY gercekadi;
+--------------+---------------------+-----------------------------+
| kullaniciadi | gercekadi | milliyeti |
+--------------+---------------------+-----------------------------+
| oktay | Oktay Altunergil | Amerika Birlesik Devletleri
|
| serkan | Serkan Hadi Ceylani | Amerika Birlesik Devletleri
|
| tayfun | Tayfun Ulu | Turkiye Cumhuriyeti |
+--------------+---------------------+-----------------------------+
3 rows in set (0.06 sec)
Evet yukarida goruldugu gibi tabloda benim,oktayin ve tayfunun
"turk-php.com" eposta adresi mevcuttur.Bu yazi yazildigi
sirada gercekten de bu uc kullanici turk-php.com da admin
olarak gorev yapmaktaydilar.Bu nedenle "kullanicilar" tablosunda
email adresleri olarak turk-php.com adresleri gorunmekteydi...
Simdi de diger karekter olan "_" alt_cizgi ile ilgili bir
ornek yapalim :
mysql> SELECT kullaniciadi FROM kullanicilar WHERE kullaniciadi
LIKE '___kan';
+--------------+
| kullaniciadi |
+--------------+
| serkan |
+--------------+
1 row in set (0.00 sec)
NOT LIKE operatoru LIKE ile tam zit olarak gorev yapar.Ornegin
sorgu sonucunda belirli bir karkter grubunun gecmemesini
istiyorsaniz :
mysql> SELECT kullaniciadi FROM kullanicilar WHERE kullaniciadi
NOT LIKE '___kan
';
+--------------+
| kullaniciadi |
+--------------+
| ahmet |
| hikmet |
| memis |
| oktay |
| tayfun |
+--------------+
5 rows in set (0.00 sec)
Tablo Alani Ile Ilgili Kisa Matematiksel Ozetler Almak
MySQL hazir fonksiyonlari kullanilarak bazen verinin kendisi
degilde o alandaki veri ile ilgili hesaplanmis bazi ozet
matematiksel sonuclarda dondurulebilir.Bunlar icin MySQL
hazir fonksiyolari kullanilir :
sum () sorgu sonucunda
donen satirlarin tooplami
max () verilen
tablo alaninda yer alan en buyuk sayi
min () verilen
tablo alaninda yer alan en kucuk sayi
avg () verilen
tablo alaninda yer alan verilerin ortalamasi
count () sorgu
sonucunda donen satir sayisi
"sayi" (integer) veri tipinde veri saklayan bir alanda minumum
ve maximum degerleri bulmak icin min () ve max () MySQL
sunucu fonksiyonlari kullanilir :
mysql> SELECT min(kullanicinumarasi), max(kullanicinumarasi)
FROM kullanicilar;
+------------------------+------------------------+
| min(kullanicinumarasi) | max(kullanicinumarasi) |
+------------------------+------------------------+
| 1 | 6 |
+------------------------+------------------------+
1 row in set (0.05 sec)
Bir sorgu sonucunda donen satir sayisi count () fonksiyonu
kullanilarak elde edilebilir :
count(alanadi)
olarak kullanilirsa verilen alandaki NULL olmayan satirlar,
count(*) olarak
kullanildiginda o alandaki butun satirlar sayilacaktir.
Ornegin 2000 yilindan once kayit yaptiran kullanicilari
saymak icin soyle bir sorgu hazirlanabilir :
mysql> SELECT count(*) FROM kullanicilar WHERE kayittarihi
< '2000-01-01';
+----------+
| count(*) |
+----------+
| 4 |
+----------+
1 row in set (0.00 sec)
Bir sonraki bolumde daha kompleks SQL yapilari ve PHP ile
hazirlanmis bir kullanici kayit betiginin nasil hazirlanacagini
gorecegiz...
Kalin Saglicakla,
Serkan Hadi Ceylani
serkan@turk-php.com
|