一千萬個為什麽

搜索

在SQL Server中截斷日期的最佳方法是什麽?

If I have a date value like 2010-03-01 17:34:12.018

將此轉換為 2010-03-01 00:00:00.000 的最有效方法是什麽?

作為次要問題,模擬Oracle的 TRUNC 函數的最佳方法是什麽,這將允許您截斷年,季,月,周,日,小時,分鐘和第二邊界?

最佳答案

要舍入到最近的整天,有三種方法可供廣泛使用。第一個使用 datediff 來查找自 0 datetime以來的天數。 0 日期時間對應於1900年1月1日。通過將日差添加到開始日期,您已整理到一整天;

select dateadd(d, 0, datediff(d, 0, getdate()))

第二種方法是基於文本的:它使用 varchar(10)截斷文本描述,只留下日期部分:

select convert(varchar(10),getdate(),111)

第三種方法使用的事實是 datetime 實際上是一個浮點,表示自1900年以來的天數。因此,通過將其四舍五入為整數,例如使用 floor ,你得到了一天的開始:

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

要回答第二個問題,一周的開始比較棘手。一種方法是減去星期幾:

select dateadd(dd, 1 - datepart(dw, getdate()), getdate())

這也會返回一個時間部分,因此您必須將其與其中一個時間剝離方法結合使用才能到達第一個日期。例如,將 @start_of_day 作為可讀性變量:

declare @start_of_day datetime
set @start_of_day = cast(floor(cast(getdate() as float)) as datetime)
select dateadd(dd, 1 - datepart(dw, @start_of_day), @start_of_day)

年,月,小時和分鐘的開始仍然適用於“自1900年以來的差異”方法:

select dateadd(yy, datediff(yy, 0, getdate()), 0)
select dateadd(m, datediff(m, 0, getdate()), 0)
select dateadd(hh, datediff(hh, 0, getdate()), 0)
select dateadd(mi, datediff(mi, 0, getdate()), 0)

Rounding by second requires a different approach, since the number of seconds since 0 gives an overflow. One way around that is using the start of the day, instead of 1900, as a reference date:

declare @start_of_day datetime
set @start_of_day = cast(floor(cast(getdate() as float)) as datetime)
select dateadd(s, datediff(s, @start_of_day, getdate()), @start_of_day)

舍入5分鐘,請調整分鐘舍入方法。取微小差異的商,例如使用/5 * 5

select dateadd(mi, datediff(mi,0,getdate())/5*5, 0)

這也適用於四分之一小時。

轉載註明原文: 在SQL Server中截斷日期的最佳方法是什麽?