Bandingkan DATETIME dan DATE dengan mengabaikan porsi waktu

151

Saya punya dua tabel di mana kolom [date]adalah tipe DATETIME2(0).

Saya harus membandingkan dua catatan hanya dengan bagian Tanggal mereka (hari + bulan + tahun), membuang bagian Waktu (jam + menit + detik).

Bagaimana saya bisa melakukan itu?

abatishchev
sumber

Jawaban:

252

Gunakan CASTuntuk DATEtipe data baru di SQL Server 2008 untuk membandingkan hanya bagian tanggal:

IF CAST(DateField1 AS DATE) = CAST(DateField2 AS DATE)
marc_s
sumber
61

Kelemahan kecil dalam jawaban Marc adalah bahwa kedua bidang tanggal telah typecast, artinya Anda tidak akan dapat meningkatkan indeks apa pun.

Jadi, jika ada kebutuhan untuk menulis kueri yang dapat mengambil manfaat dari indeks pada bidang tanggal, maka pendekatan berikut (agak berbelit-belit) diperlukan.

  • Bidang tanggal yang diindeks (sebut saja DF1) harus disentuh oleh fungsi apa pun.
  • Jadi, Anda harus membandingkan DF1 dengan rentang nilai datetime penuh untuk hari DF2.
  • Itu dari bagian tanggal dari DF2, ke bagian tanggal dari hari setelah DF2.
  • Yaitu (DF1 >= CAST(DF2 AS DATE)) AND (DF1 < DATEADD(dd, 1, CAST(DF2 AS DATE)))
  • CATATAN : Sangat penting bahwa perbandingannya adalah > = (kesetaraan diizinkan) dengan tanggal DF2, dan (secara ketat) < sehari setelah DF2. Juga operator ANTARA tidak bekerja karena memungkinkan kesetaraan di kedua sisi.

PS: Cara lain untuk mengekstrak tanggal saja (dalam versi SQL Server yang lebih lama) adalah dengan menggunakan trik bagaimana tanggal diwakili secara internal.

  • Keluarkan tanggal sebagai pelampung.
  • Potong bagian fraksinya
  • Masukkan nilai kembali ke datetime
  • Yaitu CAST(FLOOR(CAST(DF2 AS FLOAT)) AS DATETIME)
Kecewa
sumber
5

Meskipun saya membatalkan jawaban yang ditandai sebagai benar. Saya ingin menyentuh beberapa hal untuk siapa pun yang menemukan ini.

Secara umum, jika Anda memfilter khusus pada nilai Date saja. Microsoft merekomendasikan untuk menggunakan format netral bahasa ymdatau y-m-d.

Perhatikan bahwa formulir '2007-02-12' dianggap bahasa-netral hanya untuk tipe data DATE, DATETIME2, dan DATETIMEOFFSET.

Untuk melakukan perbandingan tanggal menggunakan pendekatan tersebut sederhana. Pertimbangkan contoh berikut yang dibuat-buat.

--112 is ISO format 'YYYYMMDD'
declare @filterDate char(8) = CONVERT(char(8), GETDATE(), 112)

select 
    * 
from 
    Sales.Orders
where
    CONVERT(char(8), OrderDate, 112) = @filterDate

Di dunia yang sempurna, melakukan manipulasi apa pun pada kolom yang difilter harus dihindari karena ini dapat mencegah SQL Server menggunakan indeks secara efisien. Yang mengatakan, jika data yang Anda simpan hanya peduli dengan tanggal dan bukan waktu, pertimbangkan menyimpan seperti DATETIMEtengah malam sebagai waktu. Karena:

Ketika SQL Server mengubah literal ke tipe kolom yang difilter, ia mengasumsikan tengah malam ketika bagian waktu tidak ditunjukkan. Jika Anda ingin filter seperti itu mengembalikan semua baris dari tanggal yang ditentukan, Anda harus memastikan bahwa Anda menyimpan semua nilai dengan tengah malam sebagai waktunya.

Jadi, anggap Anda hanya peduli dengan tanggal, dan simpan data Anda seperti itu. Kueri di atas dapat disederhanakan menjadi:

--112 is ISO format 'YYYYMMDD'
declare @filterDate char(8) = CONVERT(char(8), GETDATE(), 112)

select 
    * 
from 
    Sales.Orders
where
    OrderDate = @filterDate
pimbrouwers
sumber
3

Anda bisa coba yang ini

CONVERT(DATE, GETDATE()) = CONVERT(DATE,'2017-11-16 21:57:20.000')

Saya mengujinya untuk MS SQL 2014 dengan mengikuti kode

select case when CONVERT(DATE, GETDATE()) = CONVERT(DATE,'2017-11-16 21:57:20.000') then 'ok'
            else '' end
reza.cse08
sumber
-3

Untuk Bandingkan dua tanggal seperti MM / DD / YYYY hingga MM / DD / YYYY . Ingat, jenis kolom Bidang pertama harus dateTime. Contoh: columnName : payment_date dataType: DateTime .

setelah itu Anda dapat dengan mudah membandingkannya. Kueri adalah:

select  *  from demo_date where date >= '3/1/2015' and date <=  '3/31/2015'.

Sangat sederhana ...... Ini mengujinya .....

pankaj
sumber
Ini tidak cukup menjawab pertanyaan. Itu permintaan selama sebulan, bukan sehari.
Curtis Yallop
Untuk permintaan Maret Anda: Jika tanggal adalah '3/31/2015' waktu 13:00, itu tidak akan ditemukan. Anda harus menggunakan <'4/1/2015'.
Curtis Yallop
Juga pertimbangkan untuk menggunakan format tanggal internasional '2015-03-01'. Di Kanada (dan banyak tempat lain), format resmi adalah DD / MM / YYYY yang membuat kedua format ambigu dan bermasalah.
Curtis Yallop
Jawaban ini tidak berhubungan dengan 2 tabel, seperti yang diminta dalam pertanyaan.
Curtis Yallop
Ya saya setuju, tetapi saya hanya membuktikan solusi bukan solusi internasional .. Anda harus mengubah beberapa pesanan ...
pankaj