Saya punya pertanyaan seperti ini:
SELECT * FROM Cases WHERE created_at BETWEEN '2013-05-01' AND '2013-05-01'
Tapi ini tidak memberikan hasil meskipun ada data pada tanggal 1.
created_at
Sepertinya 2013-05-01 22:25:19
, saya kira itu ada hubungannya dengan waktu? Bagaimana ini bisa diselesaikan?
Ini berfungsi dengan baik jika saya melakukan rentang tanggal yang lebih besar, tetapi seharusnya (inklusif) bekerja dengan satu tanggal juga.
sql
sql-server
sql-server-2008
tsql
date
JBurace
sumber
sumber
Jawaban:
ini adalah inklusif. Anda membandingkan waktu data dengan tanggal. Tanggal kedua ditafsirkan sebagai tengah malam ketika hari dimulai .
Salah satu cara untuk memperbaikinya adalah:
Cara lain untuk memperbaikinya adalah dengan perbandingan biner eksplisit
Aaron Bertrand memiliki entri blog yang panjang pada tanggal (di sini ), di mana ia membahas ini dan masalah tanggal lainnya.
sumber
dateadd
untuk mendapatkan hari berikutnya.set dateformat dmy;select month(cast('2013-05-01' as datetime)); =1
>=
) dan terbuka di ujung lainnya (<
) dikombinasikan dengan memeriksa satu hari di luar tanggal akhir yang ditentukan.where
klausa, karena akan kehilangan pengindeksan yang dimilikinya. Ini pola yang sangat buruk.Diasumsikan bahwa referensi kencan kedua dalam
BETWEEN
sintaks secara ajaib dianggap sebagai "akhir hari" tetapi ini tidak benar .yaitu ini yang diharapkan:
tetapi yang sebenarnya terjadi adalah ini:
Yang menjadi setara dengan:
Masalahnya adalah salah satu persepsi / harapan tentang
BETWEEN
yang tidak termasuk KEDUA nilai yang lebih rendah dan nilai-nilai atas dalam kisaran, tetapi tidak secara ajaib membuat kencan yang "awal" atau "akhir".BETWEEN
harus dihindari saat memfilter menurut rentang tanggal.Selalu gunakan
>= AND <
sajatanda kurung opsional di sini tetapi bisa menjadi penting dalam pertanyaan yang lebih kompleks.
sumber
Anda perlu melakukan salah satu dari dua opsi ini:
between
kondisi Anda :... where created_at between '2013-05-01 00:00:00' and '2013-05-01 23:59:59'
(tidak disarankan ... lihat paragraf terakhir)between
. Perhatikan bahwa Anda harus menambahkan satu hari ke nilai kedua:... where (created_at >= '2013-05-01' and created_at < '2013-05-02')
Preferensi pribadi saya adalah opsi kedua. Juga, Aaron Bertrand memiliki penjelasan yang sangat jelas tentang mengapa itu harus digunakan.
sumber
BETWEEN
kueri rentang tanggal yang mencakup waktu; terlalu banyak yang bisa salah.Cukup gunakan cap waktu sebagai tanggal:
sumber
'DATE' is not a recognized built-in function name.
Perlu mengonversi stackoverflow.com/a/20973452/4233593Saya menemukan bahwa solusi terbaik untuk membandingkan bidang datetime dengan bidang tanggal adalah sebagai berikut:
Ini setara dengan inklusif antara pernyataan karena mencakup tanggal mulai dan berakhir serta yang termasuk di dalamnya.
sumber
Itu hanya akan berfungsi pada 2008 dan versi SQL Server yang lebih baru
Jika Anda menggunakan versi yang lebih lama maka gunakan
sumber
convert(varchar, created_at, 101)
hasilnya sepertidd/MM/yyyy
dan string OP adalahyyyy-MM-dd
, saya pikir jawaban ini tidak akan berfungsi;).Anda dapat menggunakan
date()
fungsi yang akan mengekstrak tanggal dari suatu waktu dan memberi Anda hasilnya sebagai tanggal inklusif:sumber
Tanggal dinamis ANTARA kueri sql
sumber