SQL Serverのdatetimeフィールドから時間部分を削除するときに、どの方法が最高のパフォーマンスを提供しますか?
a) select DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)
または
b) select cast(convert(char(11), getdate(), 113) as datetime)
2番目の方法では、どちらかといえばさらに数バイト送信しますが、変換速度ほど重要ではないかもしれません。
どちらも非常に速いように見えますが、数十万以上の行を処理するときに速度に違いがあるのでしょうか。
また、SQLの日時の時間部分を取り除くためのさらに優れた方法がある可能性はありますか?
厳密には、メソッドa
が最もリソースを消費しません。
a) select DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)
手間がかかりすぎるため、同じ合計期間100万行でCPU使用量が少なくなることが証明されています。 日付と時刻から日付を取得するためのSQL Serverでの最も効率的な方法
他の場所でも同じようなテストを見ましたが、同様の結果が得られました。
私はDATEADD/DATEDIFFが好きです。
編集、2011年10月
SQL Server 2008以降の場合は、date
にキャストできます。あるいは単にdate
を使うので削除する時間はありません。
編集、2012年1月
これがどれほど柔軟であるかのうまくいった例: SQLサーバーで丸められた時間または日付の数字によって計算する必要がある
編集、2012年5月
考えずにWHERE句などでこれを使用しないでください。列に関数またはCASTを追加すると、インデックスの使用が無効になります。ここで番号2を参照してください: http://www.simple-talk.com/sql/t-sql-programming/ten-common-sql-programming-mistakes/
さて、これにはCASTを正しく管理するための最新のSQL Server最適化バージョンの例が含まれていますが、一般にこれは悪い考えになるでしょう...
編集、2018年9月、datetime2の場合
DECLARE @datetime2value datetime2 = '02180912 11:45' --this is deliberately within datetime2, year 0218
DECLARE @datetime2Epoch datetime2 = '19000101'
select DATEADD(dd, DATEDIFF(dd, @datetime2Epoch, @datetime2value), @datetime2Epoch)
SQL Server 2008では、次のものを使用できます。
CONVERT(DATE, getdate(), 101)
もちろんこれは古いスレッドですが、完全にするためのものです。
SQL 2008からはDATEデータ型を使用できるので、単純に次のことができます。
SELECT CONVERT(DATE,GETDATE())
SELECT CAST(FLOOR(CAST(getdate() AS FLOAT)) AS DATETIME)
SQL Server 2008では、DATE日付型(TIMEデータ型もあります)があります。
CAST(GetDate() as DATE)
または
declare @Dt as DATE = GetDate()
これはまた別の答えからの、別の答えです 重複した質問:
SELECT CAST(CAST(getutcdate() - 0.50000004 AS int) AS datetime)
このマジックナンバー方式は、DATEADD方式よりもわずかに速く動作します。 (〜10%程度)
何百万ものレコードのうちの数ラウンドでのCPU時間:
DATEADD MAGIC FLOAT
500 453
453 360
375 375
406 360
しかし、これらの数字はすでに非常に高速であるため、おそらく無関係であることに注意してください。私が10万以上のレコードセットを持っていない限り、私はCPUタイムをゼロ以上に読むことさえできませんでした。
DateAddがこの目的のためのものであり、より堅牢であるという事実を考慮すると、DateAddを使用すると思います。
SELECT CAST(CAST(GETDATE() AS DATE) AS DATETIME)
私は本当に好きです:
[date] = CONVERT(VARCHAR(10), GETDATE(), 120)
120
フォーマットコードは日付をISO 8601規格に強制変換します。
'YYYY-MM-DD' or '2017-01-09'
Dplyr(R
)とパンダ(Python
)でとても使いやすいです!
CAST(round(cast(getdate()as real),0,1) AS datetime)
このメソッドは文字列関数を使用しません。 Date
は基本的に10進数の前の数字が1日の何分の一かという実データ型です。
これは私よりも早くなると思います。
見て!
方法a)とb)は常に同じ出力を持つわけではありません。
select DATEADD(dd, DATEDIFF(dd, 0, '2013-12-31 23:59:59.999'), 0)
出力:2014-01-01 00:00:00.000
select cast(convert(char(11), '2013-12-31 23:59:59.999', 113) as datetime)
出力:2013-12-31 00:00:00.000
(MS SQL Server 2005および2008 R2でテスト済み)
編集:Adamのコメントによると、これはあなたがテーブルから日付の値を読んでいる場合は起こり得ないが、あなたがあなたの日付の値をリテラルとして与える場合には起こり得る。
この質問を参照してください。
SQL Serverでdatetimeを切り捨てる方法は?
何をしても、 文字列メソッド を使わないでください。それが最悪のやり方です。
cONVERT(char(10)、GetDate()、126)を選択してください。
最初に挿入/更新の時間を削除します。オンザフライ変換に関しては、ユーザ定義関数maintanability-wiseに勝るものはありません。
select date_only(dd)
date_only
の実装はあなたが好きなものなら何でもかまいません - 今では抽象化されていてコードを呼び出すことははるかにきれいです。
すでに答えていますが、これも捨てています...これは当然のことですが、浮動小数点数から小数(時間を格納する)を捨てて全体(日付である)だけを返すことで機能します。
CAST(
FLOOR( CAST( GETDATE() AS FLOAT ) )
AS DATETIME
)
私はこの解決策を見つけた二度目... 私はこのコードをつかみました
私にとって、以下のコードは常に勝者です。
SELECT CONVERT(DATETIME, FLOOR(CONVERT(FLOAT,GETDATE())));
ここでは、SQL Serverの日時の一部を削除する機能を作りました。使用法:
create function dbo.uf_RoundDateTime(@dt as datetime, @part as char) returns datetime as begin if CHARINDEX( @part, 'smhd',0) = 0 return @dt; return cast( Case @part when 's' then convert(varchar(19), @dt, 126) when 'm' then convert(varchar(17), @dt, 126) + '00' when 'h' then convert(varchar(14), @dt, 126) + '00:00' when 'd' then convert(varchar(14), @dt, 112) end as datetime ) end
cast(floor(cast(getdate()as float))as datetime)
を意味すると思います
実数はわずか32ビットで、情報を失う可能性があります
これは最速ですcast(cast(getdate()+x-0.5 as int)as datetime)
...しかし、たったの10%高速です(about 0.49 microseconds CPU vs. 0.58)
これは推奨されていて、今私のテストでも同じ時間がかかります:DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)
SQL 2008では、SQL CLR関数は、6.5マイクロセクションに対して1.35マイクロ秒で、SQL関数を使用するよりも約5倍高速です。これは、SQL CLR関数と単純なSQL UDFの関数呼び出しオーバーヘッドがはるかに低いことを示しています。
SQL 2005では、SQL CLR関数は私のテストではこの遅い関数に対して16倍高速です。
create function dateonly ( @dt datetime )
returns datetime
as
begin
return cast(floor(cast(@dt as float))as int)
end
念のために、上記のバージョンのいくつかが機能しなかったために、誰かがここでSybaseバージョンを探している場合
CAST(CONVERT(DATE,GETDATE(),103) AS DATETIME)
select cast(cast my_datetime_field as date) as datetime)
はどうですか?これにより、同じ日付になり、時刻は00:00に設定されますが、テキストへの変換は回避され、明示的な数値の丸めも回避されます。
TSQL
を厳守するのであれば、これが時間を短縮する最も早い方法です。
select convert(datetime,convert(int,convert(float,[Modified])))
私はこの切り捨て方法がDateAdd
方法より約5%速いことを発見しました。そしてこれはこのように最も近い日に丸めるために容易に修正することができます:
select convert(datetime,ROUND(convert(float,[Modified]),0))
可能であれば、このような特別なことのために、私はCLR関数を使うのが好きです。
この場合:
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlDateTime DateOnly(SqlDateTime input)
{
if (!input.IsNull)
{
SqlDateTime dt = new SqlDateTime(input.Value.Year, input.Value.Month, input.Value.Day, 0, 0, 0);
return dt;
}
else
return SqlDateTime.Null;
}
私は、個人的には、ほとんどの場合、 ユーザー定義関数を使用します SQL Server 2005(またはそれ以前のバージョン)を扱う場合はこのために、ただし、特にWHERE句に適用する場合はUDFを使用することには特別な欠点があります。 (詳細については、下記およびこの回答に対するコメントを参照してください)。 SQL Server 2008(またはそれ以降)を使用している場合 - 下記を参照してください。
実際、私が作成するほとんどのデータベースでは、これらのUDFを最初からすぐに追加します。早急にまたは後で必要になる可能性が99%あることがわかっているからです。
私は「日付のみ」と「時間のみ」のために1つを作成します(「日付のみ」のものははるかに2つのうち最も使用されていますが)。
これは、さまざまな日付関連のUDFへのリンクです。
基本的なSQL Serverの日付、時刻、および日時関数
日付のみ取得機能
その最後のリンクは、datetimeフィールドの一部に過ぎない日付を取得するための3つ以上の異なる方法を示しており、各アプローチの長所と短所について言及しています。
UDFを使用する場合は、クエリのパフォーマンスを大幅に妨げるため、クエリ内のWHERE句の一部としてUDFを使用しないようにしてください。その主な理由は、WHERE句でUDFを使用すると、その句が non-sargable としてレンダリングされるためです。これは、SQL Serverがクエリ実行の速度を向上させるためにその句でインデックスを使用できなくなることを意味します。私のUDFの使用法を参照して、WHERE句内の "raw"日付列を頻繁に使用しますが、UDFをSELECTされた列に適用します。このように、UDFはフィルタ処理された結果セットにのみ適用され、フィルタの一部としてテーブルのすべての行には適用されません。
もちろん、これに対する絶対的な best アプローチは、SQL Server 2008(またはそれ以降)を使用して、 日付と時刻 を切り離すことです。また、UDFやその他のメカニズムを使用して、複合日時タイプから日付部分または時間部分を抽出することなく、これらを独立して効率的に照会できます。