DATETIMEとDATEを比較して、時間部分を無視する


151

[date]がのタイプである2つのテーブルがありますDATETIME2(0)

2つのレコードを日付部分(日+月+年)のみで比較し、時間部分(時間+分+秒)を破棄する必要があります。

どうやってやるの?

回答:


252

SQL Server 2008 CASTの新しいDATEデータ型を使用して、日付部分のみを比較します。

IF CAST(DateField1 AS DATE) = CAST(DateField2 AS DATE)

61

マークの答えの小さな欠点は、両方の日付フィールドが型キャストされていることです。つまり、インデックスを活用できません。

したがって、日付フィールドのインデックスを利用できるクエリを作成する必要がある場合は、次の(かなり複雑な)アプローチが必要です。

  • インデックス付き日付フィールド(DF1と呼びます)は、いかなる種類の関数からも変更されないようにする必要があります。
  • したがって、DF1をDF2の日付値の全範囲の値と比較する必要があります。
  • これは、DF2の日付部分から、DF2の後の日の日付部分までです。
  • すなわち (DF1 >= CAST(DF2 AS DATE)) AND (DF1 < DATEADD(dd, 1, CAST(DF2 AS DATE)))
  • :比較がDF2の日付と> =(等しいことが許可されている)、および(厳密に)< DF2の翌日であることが非常に重要です。また、BETWEEN演算子は、両側で等価を許可するため機能しません。

PS:(古いバージョンのSQL Serverでのみ)日付のみを抽出する別の方法は、日付が内部的にどのように表されるかのトリックを使用することです。

  • 日付を浮動小数点数としてキャストします。
  • 小数部分を切り捨てます
  • 値を日時にキャストします
  • すなわち CAST(FLOOR(CAST(DF2 AS FLOAT)) AS DATETIME)

5

私は正解としてマークされた答えを賛成しましたが。私はこれに偶然出くわした人のためにいくつかのことに触れたかった。

一般的に、日付の値のみで具体的にフィルタリングする場合。マイクロソフトでは、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

完全な世界では、フィルターされた列に対して操作を実行することは避けてください。SQLServerがインデックスを効率的に使用できなくなる可能性があるためです。とはいえ、保存するデータが時刻ではなく日付のみに関係している場合はDATETIME、時刻を午前0時と同様に保存することを検討してください。なぜなら:

SQL Serverがリテラルをフィルター処理された列の型に変換するとき、時刻部分が示されていない真夜中と見なされます。そのようなフィルターが指定された日付からすべての行を返すようにしたい場合は、時刻を午前0時としてすべての値を保存する必要があります。

したがって、日付のみに関心があると想定し、データをそのように保存します。上記のクエリは、次のように簡略化できます。

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

select 
    * 
from 
    Sales.Orders
where
    OrderDate = @filterDate

3

あなたはこれを試すことができます

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

-3

などの比較2つの日付のためのMM / DD / YYYYMM / DD / YYYY 。フィールドの最初の列タイプはdateTimeでなければならないことに注意してください。例:columnName: payment_date dataTypeDateTime

その後は簡単に比較できます。クエリは:

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

それは非常に簡単です……それはそれをテストしました.....


これは質問に完全に答えるものではありません。1日ではなく1か月間クエリを実行します。
Curtis Yallop 2016

3月のクエリの場合:日付が「2015年3月31日」の時刻13:00である場合、その日付は見つかりません。<'4/1/2015'を使用する必要があります。
Curtis Yallop 2016

また、国際日付形式「2015-03-01」の使用も検討してください。カナダ(および他の多くの場所)では、公式の形式はDD / MM / YYYYであり、どちらの形式もあいまいで問題があります。
Curtis Yallop 2016

質問で要求されているように、この回答は2つのテーブルを扱いません。
Curtis Yallop 2016

はい、同意しますが、国際的な解決策ではなく、解決策を証明するだけです。注文を変更する必要があります...
pankaj
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.