Kurs
WHERE ve HAVING, SQL’de iki temel koşul ifadesidir. Çok ileri düzeyde ya da çok basit sorgular yazıyor olun, her ikisine de ihtiyaç duyarsınız. WHERE ve HAVING’i kardeşler gibi düşünebilirsiniz. Her ikisi de benzer bir işlevi (filtreleme) yerine getirir ve sıklıkla birlikte görülür. Ancak tıpkı kardeşler gibi, belirgin özellikleri ve kendine özgü rolleri vardır.
Eğer WHERE ve HAVING’i ayırt etme sürecindeyseniz, kapsamlı ve güçlü bir başlangıç noktası olarak SQL Fundamentals beceri yoluna kaydolmanızı öneririm. Farklı SQL ifadelerini, SQL’de yürütme sırasını, SQL sorgularını iyileştirmeyi ve daha birçok kritik konuyu öğreneceksiniz.
Kısa Cevap: WHERE vs. HAVING
Kısa cevap ve pek çok kişi için kafa karışıklığının kaynağı şudur: WHERE satır düzeyindeki veriler üzerinde çalışır, HAVING ise gruplanmış veriler üzerinde çalışır. İşte bir rehber:
-
WHERE, herhangi bir gruplama veya toplulaştırma gerçekleşmeden önce satırları filtreler. Bireysel satırlara uygulanır ve toplu (aggregate) fonksiyonlarla kullanılamaz. -
HAVING, gruplama ve toplulaştırma yapıldıktan sonra grupları filtreler. Toplu fonksiyonların sonuçlarına uygulanır veGROUP BYile birlikte kullanılır.
Farkı göstermek için hızlı bir örnek
Hızlı bir örneğe bakalım. Kendi çalışma akışınızla eşlik etmek isterseniz, emlak kiralama veri setini bu GitHub deposundan indirebilirsiniz.
Diyelim ki veri setimizde kira bedeli 500 $’ın altında olan tüm mülkleri döndürmemiz gerekiyor. Veri setindeki her satırın ayrıntı düzeyi (satır başına bir mülk), sorgu koşulunun ayrıntı düzeyiyle örtüşüyor. Bu nedenle aşağıdaki sorguda WHERE kullanıyoruz:
SELECT *
FROM rentals
WHERE rental_price < 500
Sonuç şöyle görünür. Dönen 118 satır olduğuna dikkat edin.

WHERE ile basit satır filtreleme. Görsel: Yazar.
Şimdi, bir mülkler tablosu değil, ortalama kira bedeli 2.700 $’ın altında olan şehirler tablosu istediğimizi varsayalım. Her satırın bir mülke karşılık geldiği bir tablo yerine, satırları gruplandıracak ve kira bedellerini her şehir için ortalama kira bedeline toplulaştıracağız. Bu nedenle, aşağıdaki sorguda olduğu gibi HAVING kullanacağız:
SELECT city, AVG(rental_price) AS average_rent
FROM rentals
GROUP BY city
HAVING AVG(rental_price) < 2700;
Ve sonuç şöyle olur. Yalnızca bir sonuç olduğuna dikkat edin.

HAVING ile basit grup filtreleme. Görsel: Yazar.
WHERE, HAVING ve SQL’de Yürütme Sırası
WHERE’in satır düzeyinde, HAVING’in ise toplu düzeyde filtreleme yaptığını görüyoruz. Bu farkı anlamak, aynı zamanda SQL’de deyimlerin yürütülme sırasını öğrenmemizin de yolunu açar.
WHERE, GROUP BY’dan önce ve FROM’dan (ve varsa JOIN’dan) hemen sonra değerlendirilir; herhangi bir gruplama veya toplulaştırmayı işleyemez. WHERE, toplulaştırma yapılmadan önce devreye girer. Bu nedenle yalnızca satır düzeyindeki veriler üzerinde çalışır.
Öte yandan HAVING, GROUP BY ifadesinin yürütülmesinden sonra gelir. Bu da, tablo dönüştürüldükten ve kaynak tablonun ayrıntı düzeyinden farklı bir düzeyde gruplandıktan sonra devreye girdiği anlamına gelir. HAVING yeni, dönüştürülmüş tablo üzerinde çalışır.
SQL’de WHERE Koşulunu Nasıl Kullanırsınız
Bir adım geri atıp her ifadeye tek tek bakalım. WHERE ile başlayabiliriz.
WHERE söz dizimi ve deyimleri
WHERE üç farklı SQL deyiminde kullanılabilir: SELECT, UPDATE ve DELETE.
SELECT deyimlerinde WHERE
SELECT deyimlerinde, yani veritabanından veri almaya yarayan deyimlerde, WHERE doğrudan satır düzeyinde filtreleme rolünü oynar ve aşağıdaki sorguda görebileceğimiz üzere FROM ifadesinin hemen ardındaki yerini alır:
SELECT column1, column2… etc.
FROM table_name
WHERE condition;
SELECT ile kullanılan WHERE, WHERE ifadesinin en sık HAVING ile karıştırıldığı yerdir.
UPDATE deyimlerinde WHERE
Ayrıca WHERE, verinin hangi satırda güncelleneceğini belirlemek için UPDATE deyimlerinde önemli bir rol oynar; aşağıdaki söz diziminde olduğu gibi:
UPDATE table_name
SET column_name1 = value1, column_name2 = value2… etc.
WHERE condition;
DELETE deyimlerinde WHERE
WHERE, silinmesi gereken kayıtları (satırları) belirlemek için DELETE deyimlerine de faydalı bir eklentidir; burada görebilirsiniz:
DELETE FROM table_name
WHERE condition;
WHERE koşulları nasıl yazılır
WHERE koşulları basit bir mantıksal ifade olarak yazılır. Üç bölümden oluşur: değişken/operand, koşul ve değer/sonuç. WHERE koşulları için kıyaslama ve mantıksal operatörleri içeren seçeneklere bakalım.
| Operatör işareti | Açıklama | Operand veri türü |
|---|---|---|
| = | Eşittir (tarihte o gün) | Sayısal, Metin, Tarih/zaman damgası, Boolean |
| < | Küçüktür (tarihinden önce) | Sayısal, Tarih/zaman damgası |
| > | Büyüktür (tarihinden sonra) | Sayısal, Tarih/zaman damgası |
| <= | Küçük eşittir (tarihinde veya önce) | Sayısal, Tarih/zaman damgası |
| >= | Büyük eşittir (tarihinde veya sonra) | Sayısal, Tarih/zaman damgası |
| <> (!=) | Eşit değildir (tarihte değil) | Sayısal, Metin, Tarih/zaman damgası, Boolean |
| IN | Birden fazla değere eşit (birden çok tarihte) | Sayısal, Metin, Tarih/zaman damgası, Boolean (gerçi anlamsız!) |
| LIKE | Joker karakterler kullanarak metin desenini eşleştirir | Metin |
| BETWEEN | Belirli bir aralıkta yer alır | Sayısal, Tarih/zaman damgası |
| AND | Birden fazla koşulu birleştirir, hepsi doğru olmalıdır | Mantıksal (Boolean) |
| OR | Birden fazla koşulu birleştirir, en az biri doğru olmalıdır | Mantıksal (Boolean) |
| NOT | Bir koşulu olumsuzlar | Mantıksal (Boolean) |
| IS NULL | Boş (null) değerleri kontrol eder | Tüm veri türleri |
| IS NOT NULL | Boş olmayan değerleri kontrol eder | Tüm veri türleri |
İşte NOT’u IN karşılaştırma operatörüyle birlikte kullandığımız bir örnek:
SELECT *
FROM rentals
WHERE city NOT IN ('Cairo', 'Giza');
Bu ifade, Kahire ve Giza şehirlerinde olmayan tüm mülkleri döndürür.

Kahire ve Giza dışındaki mülkler. Görsel: Yazar.
WHERE kullanım örnekleri
WHERE’in SELECT, UPDATE ve DELETE deyimleriyle çalıştığını bildiğimize göre, üç kullanım senaryosunu öngörebiliriz: satır düzeyinde filtreleme, veri alma ve veri işleme.
Satır düzeyinde filtreleme
Tablomuzdaki satırları bir veya daha fazla koşula göre filtreleyebiliriz. Aşağıdaki sorgu, yalnızca villa türündeki mülkleri içerecek şekilde satırları filtreler.
SELECT *
FROM rentals
WHERE type = ‘villa’;

Villa türündeki mülkleri seçmek. Görsel: Yazar.
Veri alma
WHERE, aradığımız belirli bir veri noktasını almak için kullanılabilir. Bu, satır düzeyinde filtrelemeye benzer ancak daha özeldir. 1 Ocak 2022’de Kahire’de müsait olan mülkün kimliğini (ID) bilmemiz gerektiğini varsayarsak, şu sorguyu kullanabiliriz:
SELECT property_id
FROM rentals
WHERE available_date = '2022-01-01'
AND city = 'Cairo';

Bir veri noktasını almak. Görsel: Yazar.
Veri işleme
Son olarak, WHERE veritabanınızdaki değerleri değiştirmek ve belirli kayıtları silmek için harika bir yardımcıdır. Örneğin, 171 numaralı mülkün aslında evcil hayvan dostu olmadığını keşfettiğimizi varsayalım; pet_friendly sütununu bir UPDATE deyiminde WHERE kullanarak aşağıdaki gibi değiştirebiliriz:
UPDATE rentals
SET pet_friendly = false
WHERE property_id = 171;
SQL’de HAVING Koşulunu Nasıl Kullanırsınız
Şimdi, aynı ayrıntı düzeyinde HAVING koşuluna geçme zamanı.
HAVING söz dizimi ve deyimleri
Öncelikle şunu bilmeliyiz: HAVING koşulu yalnızca SELECT deyimlerinde kullanılabilir. Dolayısıyla sahip olabileceği tek söz dizimi şöyledir:
SELECT grouped_column, aggregate_function(aggregated_column)… etc.
FROM table_name
GROUP BY grouped_column
HAVING condition
Birden fazla gruplama sütunu ve birden fazla toplulaştırılmış sütun ekleyebileceğinizi unutmayın. Aşağıda örneklerini göreceğiz.
HAVING koşulları nasıl yazılır
WHERE’de olduğu gibi, HAVING koşulları da mantıksal ifadeler olarak yazılır; ancak bir bileşen daha vardır: toplulaştırma fonksiyonu. Dolayısıyla bir HAVING koşulu 1) Toplulaştırma fonksiyonu, 2) değişken/operand, 3) Karşılaştırma operatörü ve 4) değer/sonuçtan oluşur.
HAVING ile toplulaştırma fonksiyonları
SQL’de esasen beş toplulaştırma fonksiyonu vardır; bir de özel bir durum sayılabilecek altıncı fonksiyon bulunur. Bu fonksiyonlar şunlardır:
| Toplulaştırma fonksiyonu | Uygun veri türü |
|---|---|
| SUM() | Sayısal |
| AVG() | Sayısal |
| MIN() | Sayısal, Metin, Tarih/zaman damgası |
| MAX() | Sayısal, Metin, Tarih/zaman damgası |
| COUNT() | Sayısal, Metin, Tarih/zaman damgası, Boolean |
Bir örnek deneyelim. Burada, bir sıklık tablosu oluşturmak için COUNT() fonksiyonunu GROUP BY ile birlikte kullanıyor ve HAVING koşulunu bir filtre olarak uyguluyoruz. Özellikle, 150 kez veya daha az geçen şehirleri bilmemiz gerekiyor; bu bağlamda bu, kayıt sayısıyla ilgili olacaktır. Şu sorguyu kullanabiliriz:
SELECT city, COUNT(*) AS properties_count
FROM rentals
GROUP BY city
HAVING COUNT(*) <= 150;

HAVING ile COUNT() kullanımı. Görsel: Yazar.
Karşılaştırma ve mantıksal operatörler
HAVING, WHERE’in kabul ettiği tüm karşılaştırma ve mantıksal operatörleri kabul eder. Tek fark, HAVING ile uygun veri türünün öncelikle toplulaştırma fonksiyonuna bağlı olmasıdır; yukarıdaki tabloda görülebilir.
HAVING kullanım örnekleri
WHERE’in aksine, HAVING ifadesi UPDATE ve DELETE deyimlerinde kullanılamaz; HAVING yalnızca veri alma için kullanılır. Kabaca iki senaryoya karşılık gelir:
Grup düzeyinde filtreleme
HAVING’in yaygın ve normal kullanımı budur. Bir örnek, ortalama kira bedeli 2.700 $’ın altında olan şehirleri döndürmektir.
SELECT city, AVG(rental_price) AS avg_price
FROM rentals
GROUP BY city
HAVING AVG(rental_price) < 2700;
Tek satır filtreleme
Bu yaygın olmayan bir durumdur; ancak HAVING, yalnızca belirli bir koşulu sağlıyorsa tek satırlık bir toplulaştırmayı (örneğin bir metrik veya KPI) döndürmek için kullanılabilir. Bu, GROUP BY olmadan HAVING kullanılarak elde edilebilir. Aşağıdaki örnekte, ortalama kira bedelini yalnızca 2.800 $’ın altındaysa döndürüyoruz. Ölçüt koşulu sağlıyorsa tek satırlık bir sonuç elde ederiz; değilse boş bir tablo elde ederiz.
SELECT AVG(rental_price) as avg_price
FROM rentals
HAVING AVG(rental_price) > 2800;
WHERE ve HAVING’i Birleştirmek
WHERE ve HAVING, toplulaştırmadan önce ve sonra filtreleme yapmak üzere birleştirilebilir. Aşağıdaki örnekte, her şehirdeki mülk sayısını döndürüyoruz; yalnızca evcil hayvan dostu mülkleri sayıyor ve 80’den fazla mülke sahip şehirlerle sınırlandırıyoruz.
SELECT city, COUNT(*) AS number_properties
FROM rentals
WHERE pet_friendly = true
GROUP BY city
HAVING COUNT(*) > 80;

WHERE ve HAVING’in temel kombinasyonu. Görsel: Yazar.
WHERE ve HAVING’in Performans Açısından Farkı
WHERE koşulunun, gruplama veya toplulaştırmadan önce uygulandığını biliyoruz. Bu nedenle, sorgunun başlarında işlenen satır sayısını azalttığı için, bireysel satırları filtrelemede WHERE’in daha verimli olduğunu da bilmeliyiz.
Diğer tarafta, HAVING koşulunun toplulaştırmadan sonra uygulandığını ve gruplanmış veriye dayalı olarak sonuç kümesini filtrelediğini biliyoruz. Bu nedenle, tüm satırlar gruplandıktan sonra veriyi işlediği için, genellikle WHERE’e kıyasla daha az verimlidir; yine de toplu fonksiyonları içeren koşullar için gereklidir.
Şu sorguya bakalım:
SELECT city, COUNT(*)
FROM rentals
GROUP BY city
HAVING rental_price < 2700;
Bu sorgu verimsizdir çünkü rental_price koşulu herhangi bir toplulaştırmaya bağlı değildir — bireysel satırları filtreler. Bu sorgu önce tüm kiralıkları şehre göre gruplar, sayar ve sonra sonucu filtreler; bu da gereksiz satırların işlenmesine yol açtığı için verimsizdir. Bu nedenle, şu sorgu daha hızlı olacaktır:
SELECT city, COUNT(*)
FROM rentals
WHERE rental_price < 2700
GROUP BY city;
WHERE ve HAVING için iyileştirme ipuçları
Yukarıdakilere dayanarak, WHERE ve HAVING koşullarını kullanırken sorgularımızı nasıl optimize edebileceğimize dair bazı iyi uygulamaları görebiliriz. Büyük veri setleriniz varsa bu önemlidir.
-
Yüksek Seçicilik: Yalnızca filtrelemeniz gereken değerlere göre filtreleyin, fazlasına değil. Bu, görünümdeki satır sayısını azaltarak sorgunun verimliliğini artırır.
-
Basitlik: Gereksiz koşulları, toplulaştırmaları ve tür dönüşümlerini çıkarın. Bu fazlalıkların her biri hesaplama maliyeti getirir.
-
Erken Filtreleyin: Grup düzeyinde toplulaştırma yapıyorsanız, gruplamayı hızlandırmak için satırları
WHEREile önceden filtreleyin. Böylece, gruplamada işlenecek satır sayısını azaltırsınız.
Karşılaştırma tablosu
Düşüncelerimizi kullanışlı bir tabloda özetleyelim:
| Karşılaştırma | WHERE | HAVING |
|---|---|---|
| Ana amaç | Satır düzeyinde filtreleme | Grup düzeyinde filtreleme |
| Temel söz dizimi | SELECT column1, column2... FROM table_name WHERE condition; | SELECT grouped_column, aggregate_function(aggregated_column)... FROM table_name GROUP BY grouped_column HAVING condition; |
| Değerlendirme sırası | GROUP BY’dan önce | GROUP BY’dan sonra |
| Uyumlu deyimler | SELECT, UPDATE, DELETE | SELECT |
| Koşullar | Toplu fonksiyon içeremez | Toplu fonksiyon içermelidir |
| Kullanım alanları | Satır düzeyinde filtreleme Veri alma Veri işleme | Grup düzeyinde filtreleme Tek satır filtreleme |
| Alt sorgular | Alt sorgularla çalışabilir | CTE olarak yazılmalıdır |
Sonuç
Bu yazı boyunca SQL’de WHERE ve HAVING arasındaki temel farkı inceledik: WHERE koşulu toplulaştırmadan önce satırları filtrelerken, HAVING koşulu toplulaştırmadan sonra gruplanmış veriyi filtreler. Ayrıca, WHERE’in SELECT, UPDATE ve DELETE deyimleriyle çalışabildiği, HAVING’in ise yalnızca SELECT ile çalıştığı gibi daha az bilinen farklardan da bahsettik. Performans konusuna da kısaca değindik.
DataCamp’in SQL Basics Cheat Sheet’i, WHERE ve HAVING koşullarının güzel bir özetini ve SQL’de filtreleme nasıl yapılır konusunda bazı ipuçlarını sunar. Ayrıca SQL’e yeni başlıyorsanız, SQL Fundamentals beceri yoluna ve Associate Data Analyst in SQL kariyer yoluna göz atmak isteyebilirsiniz.

Islam, The KPI Institute’te veri danışmanıdır. Gazetecilik geçmişi olan Islam’ın yazı, felsefe, medya, teknoloji ve kültür dâhil olmak üzere farklı ilgi alanları vardır.
Sıkça Sorulan Sorular
WHERE ve HAVING arasındaki fark nedir?
WHERE satır düzeyinde, HAVING ise grup düzeyinde filtreleme yapar.
WHERE ve HAVING’i tek bir sorguda birleştirebilir miyim?
Evet, ve HAVING kullanacaksanız WHERE kullanmanız şiddetle tavsiye edilir.
WHERE, HAVING gibi toplu fonksiyonlarla çalışabilir mi?
Hayır, toplu fonksiyonlarla yalnızca HAVING çalışabilir.
WHERE ve HAVING aynı karşılaştırma ve mantıksal operatörlerle çalışır mı?
Evet, her ikisi de aynı operatörlerle çalışır; WHERE ve HAVING koşulları mantıksal ifadeler olarak yazılır.
GROUP BY olmadan HAVING kullanabilir miyim?
HAVING genellikle GROUP BY ile gruplamadan sonra kullanılır. Bunun tek istisnası tek değerli görünüm filtrelemesidir (örneğin bir metriğin hesaplanması).