- Konu sahibi
- #1
İki tarih arasındaki kayıtları sorgularken en güvenli yöntem, başlangıç tarihini dahil edip bitiş tarihini hariç tutmaktır. Örneğin 1 Ekim 2026 günü ile 2 Ekim 2026 günü arasındaki kayıtlar için
Bir tabloda
Bu sorguda 1 Ekim 2026 saat 00:00:00 ve sonrasındaki kayıtlar seçilir. 1 Kasım 2026 saat 00:00:00 ve sonrası dışarıda bırakılır. Sonuç olarak 31 Ekim gününün tamamı, saat 23:59:59.999 gibi değerler de dahil olmak üzere aralığa girer.
Bitiş tarihini hariç tutan bu yöntem, tarih-saat sütunları için genellikle en güvenli yaklaşımdır. Sorguyu bir sonraki aya taşıdığınızda yalnızca başlangıç ve bitiş değerlerini değiştirmeniz yeterlidir.
Bir günün kayıtlarını ararken bitiş değerine doğrudan aynı tarihi yazmak çoğu zaman beklenen sonucu vermez. Örneğin aşağıdaki koşul yalnızca tam olarak gece yarısına denk gelen kayıtları bulabilir:
Çünkü
Bu sorgu 15 Ekim tarihindeki tüm saatleri kapsar, 16 Ekim tarihindeki kayıtları kapsamaz.
Ancak
Tarih değerlerini uygulama kodundan sorguya eklerken metin birleştirme yapmayın. Değerleri parametre olarak gönderin; bu yaklaşım hem tarih biçimi uyuşmazlıklarını hem de SQL enjeksiyonu riskini azaltır. Örneğin sorgunun mantığı şu şekilde kalmalıdır:
Burada
Hiç kayıt dönmemesi, tabloda kesinlikle kayıt olmadığı anlamına gelmez. Tarih değerlerinin farklı saat diliminde tutulması, uygulamanın UTC kullanması, sütunun metin türünde olması veya başlangıç-bitiş değerlerinin yanlış hesaplanması da aynı sonucu doğurabilir. Önce sütunun veri türünü, bir örnek kaydın gerçek tarih-saat değerini ve uygulamanın kullandığı saat dilimini kontrol edin.
Başlangıç tarihinden önceki kayıtların gelmesi genellikle koşulun yanlış yazıldığını veya metin türündeki tarihlerin veritabanı tarafından beklediğiniz gibi karşılaştırılmadığını gösterir. Tarih sütununda dizin varsa sütunu
>= '2026-10-01' AND < '2026-10-03' koşulunu kullanabilirsiniz. Böylece saat bilgisi bulunan kayıtlar da eksiksiz alınır ve gün sonu için 23:59:59 gibi hataya açık değerler yazmanız gerekmez.Tarih aralığı sorgusunun temel yapısı
Bir tabloda
created_at adlı tarih-saat sütunu ve orders adlı sipariş tablosu bulunduğunu varsayalım. 1 Ekim 2026 ile 31 Ekim 2026 arasındaki kayıtları almak için sorgu şöyledir:
SQL:
SELECT *
FROM orders
WHERE created_at >= '2026-10-01'
AND created_at < '2026-11-01';
Bu sorguda 1 Ekim 2026 saat 00:00:00 ve sonrasındaki kayıtlar seçilir. 1 Kasım 2026 saat 00:00:00 ve sonrası dışarıda bırakılır. Sonuç olarak 31 Ekim gününün tamamı, saat 23:59:59.999 gibi değerler de dahil olmak üzere aralığa girer.
Bitiş tarihini hariç tutan bu yöntem, tarih-saat sütunları için genellikle en güvenli yaklaşımdır. Sorguyu bir sonraki aya taşıdığınızda yalnızca başlangıç ve bitiş değerlerini değiştirmeniz yeterlidir.
Yalnızca tek bir günün kayıtlarını alma
Bir günün kayıtlarını ararken bitiş değerine doğrudan aynı tarihi yazmak çoğu zaman beklenen sonucu vermez. Örneğin aşağıdaki koşul yalnızca tam olarak gece yarısına denk gelen kayıtları bulabilir:
SQL:
WHERE created_at >= '2026-10-15'
AND created_at <= '2026-10-15';
Çünkü
created_at sütununda saat bilgisi varsa 2026-10-15 değeri genellikle 2026-10-15 00:00:00 olarak değerlendirilir. 15 Ekim gününün tamamı için bir sonraki günü bitiş sınırı yapın:
SQL:
SELECT *
FROM orders
WHERE created_at >= '2026-10-15'
AND created_at < '2026-10-16';
Bu sorgu 15 Ekim tarihindeki tüm saatleri kapsar, 16 Ekim tarihindeki kayıtları kapsamaz.
BETWEEN ne zaman kullanılmalı?
BETWEEN her iki sınırı da dahil eder. Bu nedenle yalnızca tarih saklayan bir sütunda kullanılabilirliği daha açıktır:
SQL:
SELECT *
FROM events
WHERE event_date BETWEEN '2026-10-01' AND '2026-10-31';
Ancak
event_date sütununda saat de tutuluyorsa, bitiş günüyle ilgili kayıtlar beklenenden az gelebilir. Ayrıca art arda sorgulanan aralıklarda sınır değerlerinin iki kez sayılması riski vardır. Bu nedenle tarih-saat sütunlarında >= ve < koşullarını tercih edin.| Sütun türü veya ihtiyaç | Uygun koşul | Dikkat edilmesi gereken |
|---|---|---|
| Yalnızca tarih tutan sütun | BETWEEN veya >= ve = başlangıç AND < sonraki sınır | Bitiş günü için bir sonraki gün, ay veya dönem kullanılmalıdır. |
| Tek bir gün | >= gün başlangıcı AND < sonraki gün | Günün son saniyesini elle yazmayın. |
SQL:
SELECT *
FROM orders
WHERE created_at >= :start_date
AND created_at < :end_date;
Burada
:start_date aralığın başlangıcını, :end_date ise hariç tutulacak sınırı temsil eder. Ekim ayını sorguluyorsanız başlangıç 2026-10-01 00:00:00, bitiş ise 2026-11-01 00:00:00 olabilir. Kullandığınız veritabanı sürücüsünün parametre yazımı ?, @start_date veya başka bir biçimde olabilir; değişen yalnızca yer tutucunun sözdizimidir.Sonucu kontrol ederken dikkat edilmesi gerekenler
Hiç kayıt dönmemesi, tabloda kesinlikle kayıt olmadığı anlamına gelmez. Tarih değerlerinin farklı saat diliminde tutulması, uygulamanın UTC kullanması, sütunun metin türünde olması veya başlangıç-bitiş değerlerinin yanlış hesaplanması da aynı sonucu doğurabilir. Önce sütunun veri türünü, bir örnek kaydın gerçek tarih-saat değerini ve uygulamanın kullandığı saat dilimini kontrol edin.
Başlangıç tarihinden önceki kayıtların gelmesi genellikle koşulun yanlış yazıldığını veya metin türündeki tarihlerin veritabanı tarafından beklediğiniz gibi karşılaştırılmadığını gösterir. Tarih sütununda dizin varsa sütunu
DATE(created_at) veya benzeri bir fonksiyonla sarmalamak yerine aralık koşulu kullanmak, dizinin kullanılabilmesini kolaylaştırır. Aralık sorgusunun doğru sonucu; başlangıcın dahil, bitiş sınırının hariç olması ve sınırların sütundaki saat dilimiyle aynı yorumlanmasıdır.