列[date]
がDATETIME2(0)
のタイプである2つのテーブルがあります。
2つのレコードを日付部分(日+月+年)のみで比較し、時間部分(時間+分+秒)を破棄する必要があります。
どうやってやるの?
SQL Server 2008でCAST
を新しいDATE
データ型に使用して、日付部分のみを比較します。
IF CAST(DateField1 AS DATE) = CAST(DateField2 AS DATE)
Marcの答えの小さな欠点は、両方の日付フィールドが型キャストされていることです。つまり、インデックスを活用することはできません。
そのため、日付フィールドのインデックスの恩恵を受けることができるクエリを作成する必要がある場合、次の(むしろ複雑な)アプローチが必要です。
(DF1 >= CAST(DF2 AS DATE)) AND (DF1 < DATEADD(dd, 1, CAST(DF2 AS DATE)))
PS:(古いバージョンのSQL Serverで)日付のみを抽出するもう1つの方法は、日付が内部的にどのように表されるかというトリックを使用することです。
CAST(FLOOR(CAST(DF2 AS FLOAT)) AS DATETIME)
私は正しいとマークされた答えを支持しましたが。私はこれにつまずいた人のためにいくつかのことに触れたかった。
一般的に、日付の値のみで具体的にフィルタリングする場合。マイクロソフトでは、ymd
またはy-m-d
の言語ニュートラル形式を使用することをお勧めします。
フォーム '2007-02-12'は、DATE、DATETIME2、およびDATETIMEOFFSETのデータ型についてのみ、言語に依存しないと見なされることに注意してください。
前述のアプローチを使用して日付比較を行うのは簡単です。次の不自然な例を考えてみましょう。
--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
完璧な世界では、フィルター処理された列に対する操作の実行は、SQL Serverがインデックスを効率的に使用することを妨げる可能性があるため、避ける必要があります。ただし、保存するデータが時刻ではなく日付のみに関係する場合は、時刻を午前0時にDATETIME
として保存することを検討してください。なぜなら:
SQL Serverは、リテラルをフィルター処理された列の型に変換するときに、時刻部分が示されていない深夜を想定します。このようなフィルターが指定された日付のすべての行を返すようにする場合は、時刻を午前0時に設定してすべての値を保存する必要があります。
したがって、日付のみに関心があると仮定し、データをそのように保存します。上記のクエリは、次のように簡略化できます。
--112 is ISO format 'YYYYMMDD'
declare @filterDate char(8) = CONVERT(char(8), GETDATE(), 112)
select
*
from
Sales.Orders
where
OrderDate = @filterDate
これを試すことができます
CONVERT(DATE, GETDATE()) = CONVERT(DATE,'2017-11-16 21:57:20.000')
私は次のコードでMS SQL 2014のそれをテストします
select case when CONVERT(DATE, GETDATE()) = CONVERT(DATE,'2017-11-16 21:57:20.000') then 'ok'
else '' end