web-dev-qa-db-ja.com

SQL Serverで時間なしで日付を比較する最良の方法

select * from sampleTable 
where CONVERT(VARCHAR(20),DateCreated,101) 
=     CONVERT(VARCHAR(20),CAST('Feb 15 2012  7:00:00:000PM' AS DATETIME),101)

時間のない日付を比較したい

上記のクエリは大丈夫ですか?またはあなたが提案する他のより良い解決策

  • SQL Server 2005を使用しています
  • サーバーにUTC形式で保存された日付
  • このデータに対するユーザーは異なるタイムゾーンに属します
19
Ali

変換を使用しないでください-理由もなく文字列が含まれます。秘Aは、日付時刻は実際には数値であり、日は整数部(時刻は小数部)であるということです。したがって、日は値の[〜#〜] floor [〜#〜]です。これは文字列ではなく単なる数学であり、はるかに高速です

declare @when datetime = GETUTCDATE()
select @when -- date + time
declare @day datetime = CAST(FLOOR(CAST(@when as float)) as datetime)
select @day -- date only

あなたの場合、datetimeに戻す必要はありません。範囲を使用すると、最も効率的な比較が可能になります(特にインデックス付きの場合)。

declare @when datetime = 'Feb 15 2012  7:00:00:000PM'
declare @min datetime = FLOOR(CAST(@when as float))
declare @max datetime = DATEADD(day, 1, @min)

select * from sampleTable where DateCreated >= @min and DateCreated < @max
26
Marc Gravell

Dateへの単純なキャストで問題が解決します。

DECLARE @Date datetime = '04/01/2016 12:01:31'

DECLARE @Date2 datetime = '04/01/2016'

SELECT CAST(@Date as date)

SELECT CASE When (CAST(@Date as date) = CAST(@Date2 as date)) Then 1 Else 0 End
17
SubhoM
SELECT .......
FROM ........
WHERE 
CAST(@DATETIMEVALUE1 as DATE) = CAST(@DATETIMEVALUE2 as DATE)

欠点は、フィルター列をキャストしていることです。

フィルター列にインデックスがある場合、キャストしているため、SQLエンジンはインデックスを使用して日付をより効率的にフィルターできなくなります。

5
user3957458

説明

文字列の比較は高速ではないため、Dateをvarcharに変換して比較しないでください。

>=および<を使用してDateCreated列をフィルタリングすると、はるかに高速になります。

パラメーターがない場合(サンプルなどの文字列)、ISO形式<Year><Month><Day>を使用する必要があります。

サンプル

サンプルによると

DECLARE @startDate DateTime
DECLARE @endDate DateTime

SET @startDate = '20120215'
SET @endDate = DATEADD(d,1,@startDate)

SELECT * FROM sampleTable 
WHERE DateCreated >= @startDate AND DateCreated < @endDate

詳しくは

4
dknaack
SELECT * from sampleTable  
WHERE 
datediff(day, DateCreated,CAST('Feb 15 2012  7:00:00:000PM' AS DATETIME))  = 0    

最も明白なソリューションのパフォーマンステストの後、私の結果は次のとおりです。

declare @mytime int, @othertime int, @othertime2 int
declare @i int = 0
declare @dummy int
declare @emptyloop int
declare @time datetime = getdate()

while @i < 100000
begin
set @i = @i + 1
end
set @emptyloop = datediff(microsecond, @time, getdate())

set @time = getdate()

set @i = 0
while @i < 100000
begin
select @dummy = 1 WHERE datediff(day, 0,getdate())  = 0
set @i = @i + 1
end
select @othertime = datediff(microsecond, @time, getdate()) - @emptyloop

set @time = getdate()

set @i = 0
while @i < 100000
begin
select @dummy = 1 WHERE datediff(day, 0,@i)  = 0
set @i = @i + 1
end
set @mytime = datediff(microsecond, @time, getdate()) - @emptyloop


declare @when datetime = 'Feb 15 2012  7:00:00:000PM' 
declare @min datetime = FLOOR(CAST(@when as float)) 
declare @max datetime = DATEADD(day, 1, @min)  
set @time = getdate()
set @i = 0
while @i < 100000
begin
select @dummy = 1 WHERE @i >= @min and @i < @max
set @i = @i + 1
end
set @othertime2 = datediff(microsecond, @time, getdate()) - @emptyloop


select @mytime mytime, @othertime othertime, @othertime2 othertime2

結果:

mytime      othertime   othertime2
----------- ----------- -----------
117000      144000      147000

私はできるだけ正確にそれをやろうとしましたが、コメントがありませんでした。テストを実行して、全体の結果を確認してください。

1
t-clausen.dk