Tüm yazılarPerSight Ekibi · Son güncelleme: 23 Temmuz 2026 · 8 dk okuma

SQL'de Tarih Aralığına Göre Filtreleme (BETWEEN Tuzağı Dahil)

Bu ay, son 30 gün, geçen çeyrek: SQL'de tarih aralığı sorgulamanın güvenli yolu. BETWEEN'in saat bilgisiyle neden yanıltıcı olduğu ve PostgreSQL, SQL Server, MySQL, Oracle karşılıkları.

"Bu ayki siparişler", "son 30 gün", "geçen çeyreğin cirosu". Raporların neredeyse tamamı bir tarih aralığıyla başlar. Kulağa basit gelir, ama tarih kolonu saat bilgisi de tutuyorsa en sık yapılan hata tam burada saklıdır. Önce doğru kalıbı, sonra dört veritabanının kendine has fonksiyonlarını görelim.

Neden BETWEEN kullanmamalıyım?

Çok kişi "ocak ayı" için BETWEEN '2026-01-01' AND '2026-01-31' yazar. Kolon yalnızca tarihse sorun yok. Ama kolon zaman damgasıysa (timestamp), 31 Ocak saat 09:00'daki bir sipariş 2026-01-31 00:00:00 sınırının dışında kalır ve sessizce kaybolur. BETWEEN her iki ucu da dahil ettiği için bu tuzak fark edilmeden aylarca sürebilir.

Güvenli kalıp "yarı-açık aralık"tır: başlangıç dahil, bitiş hariç. Ayın ilk gününden bir sonraki ayın ilk gününe kadar, ama sonuncusu hariç:

SELECT *
FROM siparisler
WHERE tarih >= DATE '2026-01-01'
  AND tarih <  DATE '2026-02-01';
Saat bilgisi olsa da olmasa da doğru çalışır; tercih edilen kalıp budur. SQL Server DATE literalini tanımaz; orada tarihi düz metin (2026-01-01) olarak yazın.

Son 30 günü nasıl yazarım?

Sabit tarih yerine "bugünden geriye" bir aralık istediğinizde her veritabanının kendi "bugün" ve "gün çıkar" fonksiyonu devreye girer. Aynı sorgunun dört karşılığı:

-- PostgreSQL
WHERE tarih >= CURRENT_DATE - INTERVAL '30 days'

-- SQL Server
WHERE tarih >= DATEADD(DAY, -30, CAST(GETDATE() AS date))

-- MySQL
WHERE tarih >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)

-- Oracle
WHERE tarih >= TRUNC(SYSDATE) - 30
Aynı mantık, dört farklı lehçe.

Bu ay, bu yıl gibi "içinde bulunduğumuz" dönemler

İçinde bulunduğunuz ayın başını hesaplamak için PostgreSQL'de date_trunc pratiktir; sonraki ay için bir ay eklersiniz:

-- PostgreSQL: içinde bulunduğumuz ay
WHERE tarih >= date_trunc('month', CURRENT_DATE)
  AND tarih <  date_trunc('month', CURRENT_DATE) + INTERVAL '1 month';

SQL Server'da ayın son gününü EOMONTH verir; MySQL'de LAST_DAY vardır. Yine de en sağlam yaklaşım, ay sonunu "dahil" etmek yerine bir sonraki ayın başını "hariç" sınır olarak kullanmaktır; böylece saat bilgisi sizi hiç uğraştırmaz.

Saat dilimi (timezone) beni nasıl yakalar?

Kolon UTC saklıyor, siz yerel saate göre "bugün" diyorsanız, gece yarısına yakın kayıtlar bir gün kayabilir. Kural olarak, aralığı hesaplarken hem sınırların hem de kolonun aynı saat diliminde olduğundan emin olun. Bu ayrıntı özellikle günlük panolarda "sayılar neden birer gün geç?" sorusunun baş sorumlusudur.

Sık sorulan sorular

BETWEEN tarih aralıklarında hiç kullanılmaz mı?
Kolon yalnızca tarih (saatsiz) tutuyorsa BETWEEN güvenlidir ve okunur. Kolon zaman damgası (timestamp/datetime) ise ">= başlangıç AND < bir sonraki gün" kalıbını tercih edin; BETWEEN'in üst sınırı dahil etmesi orada sessiz veri kaybına yol açar.
Tarihi metin olarak karşılaştırabilir miyim?
Önerilmez. Tarihi '2026-01-01' gibi metinle karşılaştırmak biçim uyumuna bel bağlar ve indeksten yararlanmayı zorlaştırır. Tarih türüne çevirip (DATE, CAST, TO_DATE) tarih olarak karşılaştırmak hem doğru hem hızlıdır.
Yıl ya da aya göre gruplarken aralık filtresi de gerekir mi?
Genelde evet. Önce WHERE ile ilgilendiğiniz aralığı süzer, sonra GROUP BY ile yıla/aya göre toplarsınız. Aralığı filtrelemeden tüm tabloyu gruplamak hem yavaştır hem de istemediğiniz dönemleri sonuca katar.
"Geçen çeyrek" gibi dönemleri nasıl hesaplarım?
Çeyreğin başlangıç ve bitiş tarihini hesaplayıp yine yarı-açık aralık olarak verirsiniz. PostgreSQL'de date_trunc('quarter', ...) bu işi kolaylaştırır; diğer veritabanlarında çeyreğin ilk ayını elle hesaplarsınız.

Hangi tarih fonksiyonunun hangi motora ait olduğuyla uğraşmak istemezseniz, PerSight'a "bu ayki siparişler" ya da "son 30 günün gününe göre cirosu" demeniz yeterli. Bağlı olduğunuz veritabanına uygun sorguyu o kurar, siz yalnızca sonucu okursunuz.

Kaynaklar