1. ホーム
  2. sql-server

[解決済み】SQL Serverでdatetimeを切り捨てるにはどうすればよいですか?

2022-04-14 11:40:16

質問

SQL Server 2008でdatetimeの値を切り捨てる(時間、分、秒を削除する)最良の方法は何でしょうか?

例えば

declare @SomeDate datetime = '2009-05-28 16:30:22'
select trunc_date(@SomeDate)

-----------------------
2009-05-28 00:00:00.000

解決方法は?

これは数年経った今でも頻繁に追加票を集め続けているので、最新のバージョンの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日目に足すことで動作します。

高速な方法

cast(floor(cast(getdate() as float)) as datetime)

これは、datetimeカラムが8バイトのバイナリ値として格納されているために動作します。それらをfloatにキャストし、floorで端数を取り除き、datetimeにキャストし直すと、値の時間部分が消えます。これは複雑なロジックを必要とせず、ビットシフトを行うだけなので 非常に は高速です。

これは、マイクロソフトがいつでも、たとえ自動サービスアップデートであっても、自由に変更できる実装の詳細に依存していることに注意してください。また、移植性もあまりよくありません。実際には、この実装がすぐに変更されることはないでしょうが、それでも、この実装を使用する場合は、その危険性を認識しておくことが重要です。そして今は、日付としてキャストするオプションがあるので、ほとんど必要ありません。

間違った方法

cast(convert(char(11), getdate(), 113) as datetime)

間違った方法では、文字列に変換し、文字列を切り捨てて、再びdatetimeに変換して動作します。これは 誤った という2つの理由からです。1)すべてのロケールで動作しない可能性があること、2)可能な限り最も遅い方法であること、です。


更新情報 この投稿以来、Sql Server は "correct" と "fast" のパフォーマンスの違いを最適化して取り除いてくれるという確かな証拠をいくつか目にしたので、これを追加したいと思います。

いずれの場合も そもそもこのようなことをする必要がないようにクエリを書く . この作業をデータベース上で行うことは非常に稀です。

ほとんどの場合、データベースはすでにボトルネックになっています。 一般に、パフォーマンスを向上させるためにハードウェアを追加するのに最もコストがかかり、その追加を適切に行うのが最も難しいサーバーです(たとえば、ディスクとメモリのバランスを取る必要があります)。 また、技術的にもビジネスの観点からも、規模を拡大するのが最も難しいサーバーです。技術的には、データベースサーバーよりもウェブサーバーやアプリケーションサーバーを追加する方がはるかに簡単ですし、仮にそうだとしても、IISやアパッチにサーバーライセンスあたり2万ドル以上支払う必要はありません。

私が言いたいのは、可能な限り、この作業はアプリケーション・レベルで行うべきだということです。 そのため のみ Sql Server で日付時刻を切り捨てる必要があるのは、日ごとにグループ化する必要がある場合です。その場合でも、計算カラムとして追加のカラムを設定し、挿入/更新時に維持するか、アプリケーションロジックで維持する必要があります。インデックスを壊し、CPUに負担をかけるこの作業をデータベースから取り除くことができます。