MySQL’de Temel SELECT Sorgusu Nasıl Yazılır
Veritabanı yönetiminin temel taşlarından biri olan SELECT sorgusu, MySQL ve MariaDB dünyasında her şeyin başladığı noktadır. Bir sistem yöneticisi olarak sunucularınızda MySQL çalıştırıyorsanız, eninde sonunda uygulama geliştiricilerinden “şu tablodan şu veriyi çekebilir misin?” sorusunu duyacaksınız ya da kendiniz bir şeyleri araştırmanız gerekecek. Bu yazıda SELECT sorgusunun temellerini, gerçek dünya senaryolarıyla birlikte ele alacağız.
SELECT Sorgusuna Giriş
SELECT, SQL dilinin en çok kullanılan komutudur. Basitçe söylemek gerekirse bir veya daha fazla tablodan veri okumak için kullanılır. Yazma işlemi yapmaz, veriyi değiştirmez, sadece okur. Bu yüzden güvenli bir komuttur ve production ortamında bile çekinmeden kullanabilirsiniz (tabii ki gereksiz yük oluşturmadığınız sürece).
Temel sözdizimi şu şekildedir:
SELECT kolon1, kolon2, ... FROM tablo_adi;
Ya da tüm kolonları çekmek istiyorsanız:
SELECT * FROM tablo_adi;
Yıldız karakteri (*) “tüm kolonları getir” anlamına gelir. Küçük tablolarda ve test ortamlarında kullanışlıdır ama büyük tablolarda performans sorunlarına yol açabilir. Bu konuya ilerleyen bölümlerde döneceğiz.
MySQL’e Bağlanmak ve İlk Sorguyu Çalıştırmak
Öncelikle MySQL komut satırına nasıl bağlandığımızı hatırlayalım. Terminalde şu komutu çalıştırıyoruz:
mysql -u root -p
Parola girdikten sonra MySQL prompt’una düşüyoruz. Şimdi hangi veritabanlarının mevcut olduğunu görelim:
SHOW DATABASES;
Çalışmak istediğimiz veritabanını seçiyoruz. Örneğin bir WordPress sitesinin veritabanını inceleyelim:
USE wordpress_db;
SHOW TABLES;
Bu komutlardan sonra artık o veritabanındaki tablolara SELECT sorgusu yazabiliriz. Pratik yapmak için bir tablo seçelim. WordPress veritabanındaki wp_users tablosu iyi bir başlangıç noktasıdır.
En Basit SELECT Örneği
SELECT * FROM wp_users;
Bu sorgu wp_users tablosundaki tüm satırları ve tüm kolonları getirir. Küçük bir tabloda sorun yok ama binlerce kullanıcı varsa ekran dolup taşar. Gerçek dünya senaryosunda bu sorguyu doğrudan production’da çalıştırmak pek akıllıca değil. Ama test ortamında veya küçük tablolarda gayet işe yarar.
Belirli Kolonları Seçmek
Her zaman tüm kolonlara ihtiyacınız olmaz. Sadece ihtiyaç duyduğunuz kolonları belirtmek hem performansı artırır hem de sonucu okunabilir hale getirir. Örneğin WordPress kullanıcı tablosundan sadece kullanıcı adı ve e-posta adresini çekmek isteyelim:
SELECT user_login, user_email FROM wp_users;
Bu sorgu çok daha temiz bir çıktı verir. Sistem yöneticisi olarak sıklıkla başvuracağınız bir pattern bu. Örneğin bir uygulamanın veritabanında hangi kullanıcıların kayıtlı olduğunu hızlıca görmek istediğinizde bu yöntemi kullanırsınız.
WHERE ile Koşullu Sorgular
WHERE koşulu, SELECT sorgusunu gerçekten güçlü kılan kısımdır. Sadece belirli kriterlere uyan satırları getirmek için kullanılır.
Senaryo: Production sunucusunda bir kullanıcının hesabıyla ilgili sorun var ve o kullanıcının bilgilerini kontrol etmeniz gerekiyor.
SELECT user_login, user_email, user_registered
FROM wp_users
WHERE user_login = 'ahmet_yilmaz';
Birden fazla koşul kullanmak için AND ve OR operatörlerini kullanabilirsiniz:
SELECT user_login, user_email, user_registered
FROM wp_users
WHERE user_registered > '2024-01-01'
AND user_status = 0;
Bu sorgu 2024 yılından sonra kayıt olan ve aktif statüdeki kullanıcıları getirir. WHERE koşulunda kullanabileceğiniz karşılaştırma operatörleri şunlardır:
- =: Eşittir
- != veya : Eşit değildir
- >: Büyüktür
- <: Küçüktür
- >=: Büyük eşittir
- <=: Küçük eşittir
- LIKE: Desen eşleştirme (wildcard)
- IN: Belirtilen değerler listesinde mi?
- BETWEEN: İki değer arasında mı?
- IS NULL: Değer boş mu?
- IS NOT NULL: Değer dolu mu?
LIKE ile Desen Araması
LIKE operatörü özellikle log analizi ve veri temizliği sırasında çok işe yarar. Yüzde (%) işareti herhangi bir karakter dizisini, alt çizgi (_) ise tek bir karakteri temsil eder.
Senaryo: Bir şirketin posta sunucusu verilerini kontrol ediyorsunuz ve belirli bir domain’den gelen kullanıcıları bulmak istiyorsunuz:
SELECT user_login, user_email
FROM wp_users
WHERE user_email LIKE '%@sirket.com';
Ya da kullanıcı adı “admin” ile başlayanları bulmak için:
SELECT user_login, user_email, user_registered
FROM wp_users
WHERE user_login LIKE 'admin%';
LIKE kullanırken dikkat etmeniz gereken nokta, büyük tablolarda performansı olumsuz etkileyebileceğidir. Özellikle başında yüzde işareti olan aramalar (LIKE ‘%kelime’) index kullanamaz ve tüm tabloyu tarar. Buna “full table scan” denir ve production’da sorun çıkarabilir.
ORDER BY ile Sıralama
Sonuçları belirli bir kolona göre sıralamak için ORDER BY kullanılır. Varsayılan sıralama artan (ASC) yönündedir, azalan sıralama için DESC kullanılır.
SELECT user_login, user_email, user_registered
FROM wp_users
ORDER BY user_registered DESC;
Bu sorgu en son kayıt olan kullanıcıları önce gösterir. Sunucu yönetiminde kullanıcı aktivitesini takip ederken çok işe yarar.
Birden fazla kolona göre sıralama da yapabilirsiniz:
SELECT user_login, user_email, user_registered
FROM wp_users
ORDER BY user_status ASC, user_registered DESC;
LIMIT ile Sonuç Sayısını Kısıtlamak
LIMIT komutu, büyük tablolarda çalışırken hayat kurtarır. Production’da milyonlarca satır içeren bir tabloya yanlışlıkla SELECT * çektiğinizde ne olur? Sunucu kaynakları tükenir, uygulama yavaşlar, belki de sunucu kitlenir. LIMIT bu durumu önler.
SELECT * FROM wp_posts
ORDER BY post_date DESC
LIMIT 10;
Bu sorgu en son 10 gönderiyi getirir. Daha da pratik bir kullanım için LIMIT ile birlikte OFFSET kullanabilirsiniz. Sayfalama işlemlerinde bu kombinasyon çok yaygındır:
SELECT post_title, post_date, post_status
FROM wp_posts
WHERE post_status = 'publish'
ORDER BY post_date DESC
LIMIT 10 OFFSET 20;
Bu sorgu 21. satırdan başlayarak 10 kayıt getirir, yani 3. sayfanın verilerini döner (eğer sayfa başına 10 kayıt gösteriliyorsa).
Sistem yöneticisi olarak önerim şu: Yeni bir tablo inceliyorsanız ve içeriği hakkında fikriniz yoksa her zaman önce LIMIT 5 veya LIMIT 10 ile başlayın. Ne olduğunu gördükten sonra daha geniş sorgular çalıştırın.
COUNT, SUM ve Diğer Aggregate Fonksiyonlar
Veri saymak ve toplamak için aggregate fonksiyonlar kullanılır. Bunlar özellikle raporlama ve monitoring senaryolarında çok kullanışlıdır.
COUNT: Satır sayısını döner.
SELECT COUNT(*) FROM wp_users;
Bu sorgu tablodaki toplam kullanıcı sayısını verir. Bir uygulamayı devir teslim alırken veya audit sırasında kullanışlıdır.
Daha spesifik bir örnek:
SELECT COUNT(*) as aktif_kullanici_sayisi
FROM wp_users
WHERE user_status = 0;
Burada “as” kullanarak kolona bir takma isim (alias) verdik. Bu, özellikle birden fazla aggregate fonksiyon kullandığınızda çıktıyı okunabilir yapar.
Senaryo: Bir e-ticaret sitesinin veritabanını yönetiyorsunuz. Hangi durumda kaç sipariş olduğunu görmek istiyorsunuz:
SELECT order_status, COUNT(*) as siparis_adedi
FROM wp_woocommerce_order_items
GROUP BY order_status
ORDER BY siparis_adedi DESC;
GROUP BY ile Gruplama
GROUP BY, aynı değere sahip satırları gruplamak için kullanılır. Genellikle aggregate fonksiyonlarla birlikte kullanılır.
Senaryo: Aylık kayıt olan kullanıcı sayısını görmek istiyoruz:
SELECT
YEAR(user_registered) as yil,
MONTH(user_registered) as ay,
COUNT(*) as kayit_sayisi
FROM wp_users
GROUP BY YEAR(user_registered), MONTH(user_registered)
ORDER BY yil DESC, ay DESC;
Bu sorgu yıl ve ay bazında gruplayarak her dönemdeki kayıt sayısını döner. Büyüme trendlerini analiz etmek için mükemmeldir.
HAVING ile Gruplara Koşul Eklemek
WHERE koşulu satırlara uygulanırken, HAVING koşulu gruplara uygulanır. GROUP BY ile birlikte kullanılır.
Senaryo: En az 5 siparişi olan müşterileri bulmak istiyoruz:
SELECT customer_email, COUNT(*) as siparis_sayisi
FROM orders
GROUP BY customer_email
HAVING COUNT(*) >= 5
ORDER BY siparis_sayisi DESC;
WHERE ile HAVING arasındaki fark kritiktir:
- WHERE: GROUP BY’dan önce çalışır, ham satırları filtreler
- HAVING: GROUP BY’dan sonra çalışır, grupları filtreler
DISTINCT ile Tekrarlayan Değerleri Kaldırmak
Bir kolonda kaç farklı değer olduğunu görmek ya da tekrarlayan kayıtları temizlemek için DISTINCT kullanılır.
SELECT DISTINCT post_status FROM wp_posts;
Bu sorgu wp_posts tablosunda kaç farklı post_status değeri olduğunu gösterir. Veri kalitesini kontrol ederken çok işe yarar.
Pratik senaryo: Hangi IP adreslerinden sisteme giriş yapıldığını görmek istiyorsunuz:
SELECT DISTINCT ip_address, COUNT(*) as giris_sayisi
FROM login_logs
WHERE login_date > DATE_SUB(NOW(), INTERVAL 7 DAY)
GROUP BY ip_address
ORDER BY giris_sayisi DESC
LIMIT 20;
Bu sorgu son 7 günde giriş yapılan farklı IP adreslerini ve her birinin giriş sayısını listeler. Şüpheli aktivite tespitinde güzel bir başlangıç noktasıdır.
NULL Değerlerle Çalışmak
NULL, veritabanında “değer yok” anlamına gelir ve normal karşılaştırma operatörleriyle sorgulanamaz. NULL kontrolü için IS NULL veya IS NOT NULL kullanmalısınız.
SELECT user_login, user_email
FROM wp_users
WHERE user_activation_key IS NOT NULL;
Bu sorgu henüz e-posta doğrulaması yapmamış kullanıcıları getirir. NULL değerleri normal = operatörüyle karşılaştırmak her zaman FALSE döner, bu yaygın bir hatadır. Şöyle bir sorgu:
-- BU CALISMAZ
SELECT * FROM wp_users WHERE user_activation_key = NULL;
Hiçbir sonuç getirmez çünkü NULL ile karşılaştırma her zaman belirsiz (NULL) döner. Bunun yerine:
SELECT * FROM wp_users WHERE user_activation_key IS NULL;
Gerçek Dünya Senaryosu: Veritabanı Sağlık Kontrolü
Bir sistem yöneticisi olarak sıkça yapmanız gereken işlemlerden biri veritabanı sağlık kontrolüdür. İşte bu amaçla kullanabileceğiniz pratik bir sorgu seti:
-- Tablodaki toplam kayit sayisi ve en son kayit tarihi
SELECT
COUNT(*) as toplam_kayit,
MIN(user_registered) as ilk_kayit,
MAX(user_registered) as son_kayit,
COUNT(CASE WHEN user_status = 0 THEN 1 END) as aktif_kullanici,
COUNT(CASE WHEN user_status = 1 THEN 1 END) as pasif_kullanici
FROM wp_users;
Bu tek sorgu size tablonun genel durumu hakkında özet bilgi verir. Bir uygulamayı ilk kez incelediğinizde bu tür özet sorgular büyük zaman kazandırır.
Sorgularda Yorum Satırları Kullanmak
Uzun ve karmaşık sorguları anlaşılır tutmak için yorum satırları eklemek iyi bir alışkanlıktır. MySQL’de iki tür yorum vardır:
-- Bu tek satirli bir yorum
SELECT
user_login, -- Kullanici adi
user_email, -- E-posta adresi
user_registered -- Kayit tarihi
FROM wp_users
/* Bu cok satirli
bir yorumdur */
WHERE user_status = 0
ORDER BY user_registered DESC
LIMIT 50;
Script yazarken veya sorguları belgelendirirken bu pratiği edinmenizi tavsiye ederim. Özellikle 3 ay sonra aynı scripte baktığınızda kendinize teşekkür edeceksiniz.
Performans İpuçları
Sorgularınızı yazarken aklınızda bulundurmanız gereken bazı önemli noktalar var:
- SELECT * kullanmaktan kaçının: Sadece ihtiyacınız olan kolonları belirtin. Bu hem ağ trafiğini azaltır hem de sunucu üzerindeki yükü düşürür.
- LIMIT kullanın: Özellikle production ortamında büyük tablolara sorgular yazarken her zaman LIMIT ekleyin.
- WHERE koşulunu indeksli kolonlara göre yazın: Indeksli kolonlar üzerinde WHERE koşulu kullanmak sorguyu dramatik biçimde hızlandırır.
- LIKE ‘%kelime’ kullanımından kaçının: Baştaki yüzde işareti indeksi devre dışı bırakır. Mümkünse ‘kelime%’ şeklinde kullanın.
- COUNT() ile COUNT(kolon) farkını bilin: COUNT() tüm satırları sayar, COUNT(kolon) ise NULL olmayan değerleri sayar.
- EXPLAIN kullanın: Bir sorgunun nasıl çalıştığını görmek için sorgunun önüne EXPLAIN ekleyin. Bu, yavaş sorguları debug etmede altın değerindedir.
EXPLAIN SELECT * FROM wp_users WHERE user_email = '[email protected]';
Sonuç
SELECT sorgusu MySQL ve MariaDB dünyasının kapı anahtarıdır. Temel sözdizimini anladıktan sonra WHERE, ORDER BY, LIMIT, GROUP BY ve aggregate fonksiyonları birleştirerek oldukça güçlü sorgular yazabilirsiniz. Sistem yöneticisi perspektifinden bakıldığında bu sorgular; kullanıcı yönetimi, uygulama sorunlarını debug etme, veri analizi ve sağlık kontrolleri gibi onlarca farklı senaryoda günlük işlerinize değer katacak.
En önemli tavsiyem şu: Yeni bir veritabanı ortamında çalışırken her zaman LIMIT ekleyin ve SELECT *’den kaçının. Production ortamında yanlışlıkla milyonlarca satır çekmek, hem sizi hem de uygulamayı zor durumda bırakabilir. Küçük adımlarla ilerleyin, önce veriyi tanıyın, sonra daha karmaşık sorgulara geçin. Bir sonraki yazıda JOIN sorgularına bakacağız, birden fazla tabloyu bir arada sorgulamak işleri gerçekten ilginç hale getiriyor.
