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 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 日目に追加することで機能します。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) これを行うには可能な限り遅い方法であるということです...そして少しだけではありません。他のオプションよりも 1 桁か 2 桁遅くなります。
更新これは最近いくつかの投票を得ているため、これを投稿して以来、Sql Serverが「正しい」方法と「速い」方法のパフォーマンスの違いを最適化するというかなり確かな証拠を見たことを追加したいと思います、つまり、前者を優先する必要があります。
どちらの場合でも、そもそもこれを行う必要がないように、クエリを作成する必要があります。データベースでこの作業を行う必要があることは非常にまれです。
ほとんどの場所で、データベースはすでにボトルネックになっています。通常、パフォーマンスを向上させるためにハードウェアを追加するのに最も費用がかかり、それらの追加を適切に行うのが最も難しいのはサーバーです (たとえば、ディスクとメモリのバランスを取る必要があります)。また、技術的にもビジネスの観点からも、外部への拡張が最も困難です。技術的には、データベース サーバーよりも Web サーバーまたはアプリケーション サーバーを追加する方がはるかに簡単です。たとえそれが間違っていたとしても、IIS または apache のサーバー ライセンスごとに 20,000 ドル以上支払う必要はありません。
私が言いたいのは、可能な限り、この作業をアプリケーション レベルで行うべきだということです。Sql Server で datetime を切り捨てるのは、日ごとにグループ化する必要がある場合だけです。その場合でも、追加の列を計算列として設定するか、挿入/更新時に維持するか、維持する必要があります。アプリケーションロジックで。このインデックスを破る、CPU を大量に消費する作業をデータベースから取り除きます。
SQL Server 2008 のみ
CAST(@SomeDateTime AS Date)
次に、必要に応じてdatetimeにキャストします
CAST(CAST(@SomeDateTime AS Date) As datetime)
より完全な答えを出すために、これは、日付の一部を切り捨てて分を含めるための有効な方法です(切り捨てるGETDATE()
日付に置き換えてください)。
dd
これは、(日)だけでなく、任意の日付部分を使用できるという点で、受け入れられた回答とは異なります(ここを参照)。
dateadd(minute, datediff(minute, 0, GETDATE()), 0)
上記の式では、0
は年の初め(1900-01-01)の定数日付であることに注意してください。秒やミリ秒などの小さな部分に切り捨てる必要がある場合は、オーバーフローを回避するために、切り捨てられる日付に近い一定の日付を取得する必要があります。
これをしなければならなかったときにウェブで見つけたスニペットは次のとおりです。
dateadd(dd,0, datediff(dd,0, YOURDATE))
e.g.
dateadd(dd,0, datediff(dd,0, getDate()))
CONVERT(DATE, <yourdatetime>) or CONVERT(DATE, GetDate()) or CONVERT(DATE, CURRENT_TIMESTAMP)
SQl 2005 では、trunc_date 関数は次のように記述できます。
(1)
CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
CAST(FLOOR( CAST( @date AS FLOAT ) )AS DATETIME)
END
最初の方法ははるかにクリーンです。最後の CAST() を含む 3 つのメソッド呼び出しのみを使用し、文字列連結を実行しません。これは自動プラスです。さらに、ここには巨大な型キャストはありません。日付/時刻スタンプを表すことができると想像できる場合、日付から数値への変換と日付への変換はかなり簡単なプロセスです。
(2)
CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
SELECT CONVERT(varchar, @date,112)
END
Microsoft の datetimes (2) または (3) の実装が心配な場合は、問題ないかもしれません。
(3)
CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
SELECT CAST((STR( YEAR( @date ) ) + '/' +STR( MONTH( @date ) ) + '/' +STR( DAY(@date ) )
) AS DATETIME
END
3 つ目は、より詳細な方法です。これには、日付を年、月、日の部分に分割し、それらを「yyyy/mm/dd」形式にまとめてから、日付にキャストする必要があります。このメソッドには、文字列の連結は言うまでもなく、最後の CAST() を含む 7 つのメソッド呼び出しが含まれます。
ここに来て、DATETIME フィールドを 1 日未満 (たとえば 1 分ごと) に切り詰める方法を探している人は、次のように使用できます。
SELECT CAST(FLOOR(CAST(GETDATE() AS FLOAT)) + (FLOOR((CAST(GETDATE() AS FLOAT) - FLOOR(CAST(GETDATE() AS FLOAT))) * 1440.0) + (3.0/86400000.0)) / 1440.0 AS DATETIME)
したがって、今日が である場合2010-11-26 14:54:43.123
、これは を返し2010-11-26 14:54:00.000
ます。
短縮する間隔を変更するには、1440.0 を 1 日の間隔の数に置き換えます。次に例を示します。
24hrs = 24.0 (for every hour)
24hrs / 0.5hrs = 48.0 (for every half hour)
24hrs / (1/60) = 1440.0 (for every minute)
.0
(暗黙的に float にキャストするには、常に最後に aを付けます。)
私の計算で が何のためにあるのか疑問に思っている方のために説明すると、SQL Server 2005 は からに正確(3.0/86400000)
にキャストしないようです。FLOAT
DATETIME
オラクル:
TRUNC(SYSDATE, 'MONTH')
SQLサーバー:
DATEADD(DAY, - DATEPART(DAY, DateField) + 1, DateField)
同様に、日付から分または時間を切り捨てるために使用できます。
これを参照してください: http://microsoftmiles.blogspot.com/2006/11/remove-time-from-datetime-in-sql-server.html
trunc(sysdate)
このクエリにより、Oracleと同等の結果が得られるはずです。
SELECT *
FROM your_table
WHERE CONVERT(varchar(12), your_column_name, 101)
= CONVERT(varchar(12), GETDATE(), 101)
お役に立てれば!
using Substring
datetime 変数から日付を抽出することもできます。また、datetime にキャストすると時間部分が無視されます。
declare @SomeDate datetime = '2009-05-28 16:30:22'
SELECT cast(substring(convert(varchar(12),@SomeDate,111),0,12) as Datetime)
また、datetime 変数の一部にアクセスし、それらを次のように切り捨てられた日付にマージすることもできます。
SELECT cast(DATENAME(year, @Somedate) + '-' +
Convert(varchar(2),DATEPART(month, @Somedate)) + '-' +
DATENAME(day, @Somedate)
as datetime)
TRUNC(aDate, 'DD') は、分、秒、および時間を切り捨てます
SRC: http://www.techonthenet.com/oracle/functions/trunc_date.php