SQL Server で日時値を切り捨てる (時間、分、秒を削除する) 最適な方法は何ですか?
例えば:
declare @SomeDate datetime = '2009-05-28 16:30:22'
select trunc_date(@SomeDate)
-----------------------
2009-05-28 00:00:00.000
ベストアンサー1
これは、数年経った今でも頻繁に追加投票を集め続けているため、Sql Server の最新バージョンに合わせて更新する必要があります。Sql Server 2008 以降の場合は簡単です。
cast(getdate() as Date)
下部近くの最後の 3 つの段落は依然として適用され、多くの場合、一歩下がって、そもそもキャストを回避する方法を見つける必要があることに注意してください。
しかし、これを実現する方法は他にもあります。ここでは最も一般的な方法を紹介します。
正しい方法 (Sql Server 2008 以降の新機能)
cast(getdate() as Date)
正しい方法(古い)
dateadd(dd, datediff(dd, 0, getdate()), 0)
これは今では古いものですが、月、分、時間、年の最初の瞬間など、他の時点にも簡単に適応できるため、知っておく価値はまだあります。
この正しい方法では、ANSI 標準の一部であり、動作が保証されている文書化された関数を使用しますが、多少遅くなる可能性があります。この方法は、0 日目から現在の日までの日数を調べ、その日数を 0 日目に追加することで機能します。 のdatetime
保存方法やロケールに関係なく機能します。
早道
cast(floor(cast(getdate() as float)) as datetime)
これが機能するのは、datetime
列が 8 バイトのバイナリ値として保存されているためです。それらを にキャストしfloat
、floor
小数部を削除すると、値の時間部分は にキャストし直すとなくなりますdatetime
。これはすべて、複雑なロジックを必要とせず、ビットシフトするだけなので、非常に高速です。
これは、自動サービス更新であっても Microsoft がいつでも自由に変更できる実装の詳細に依存していることに注意してください。また、移植性もあまり高くありません。実際には、この実装がすぐに変更される可能性はほとんどありませんが、使用することを選択した場合は、危険性を認識しておくことが重要です。また、日付としてキャストするオプションが追加されたため、これが必要になることはほとんどありません。
間違ったやり方
cast(convert(char(11), getdate(), 113) as datetime)
間違った方法は、文字列に変換し、文字列を切り捨てて、日時に戻すというものです。これは、次の 2 つの理由から間違っています。
- すべての地域で機能するとは限りません。
- これは、これを行う最も遅い方法です。少し遅いというだけでなく、他のオプションよりも 1 桁または 2 桁遅くなります。
更新最近、この投稿に投票が集まっています。そのため、この投稿をしてから、Sql Server が「正しい」方法と「高速」な方法のパフォーマンスの違いを最適化するというかなり確かな証拠を見たので、前者を優先すべきだということを付け加えておきたいと思います。
どちらの場合でも、そもそもこれを実行する必要がないようにクエリを記述する必要があります。データベースでこの作業を実行する必要があることは非常にまれです。
ほとんどの場合、データベースはすでにボトルネックになっています。一般的に、パフォーマンス向上のためにハードウェアを追加するのに最も費用がかかり、追加を適切に行うのが最も難しいサーバーです (たとえば、ディスクとメモリのバランスを取る必要があります)。また、技術的にもビジネスの観点からも、拡張が最も難しいサーバーです。技術的には、Web サーバーまたはアプリケーション サーバーを追加する方がデータベース サーバーを追加するよりもはるかに簡単です。また、それが間違っていたとしても、IIS または Apache のサーバー ライセンスごとに 20,000 ドル以上を支払う必要はありません。
私が言いたいのは、可能な限り、この作業をアプリケーション レベルで実行する必要があるということです。SQL Server で切り捨てを行う必要があるのは、日ごとにグループ化する必要がある場合のみdatetime
です。その場合でも、計算列として追加の列を設定し、挿入/更新時に維持するか、アプリケーション ロジックで維持する必要があります。インデックスを破壊し、CPU を大量に消費するこの作業をデータベースから取り除いてください。