Sql-Server

帶有毫秒的 DATEADD 和 DATEPART 會產生奇怪的結果

  • September 9, 2020

我有一個表格,其中包含 unix 時間的日期和一個單獨的毫秒欄位。我現在嘗試從這兩個欄位中創建一個日期以供以後計算(例如在時間範圍內過濾)。將毫秒添加到通過…創建的日期後

dateadd(S, [timestamp_s], '1970-01-01')

通過添加另一個DATEADD

dateadd(MS, [timestamp_ms], dateadd(S, [timestamp_s], '1970-01-01')) eventdate

…然後輸出毫秒的日期,有時會減少一毫秒。出於好奇,然後我嘗試提取毫秒數,看看它給出了什麼,然後又減少了 1 毫秒。

在此處輸入圖像描述

我認為這與內部浮點精度有關,但我在數據中看不到任何規則。有時每個操作會減少 1 MS,有時第一個操作會減 1,但 DATEPART 會再次加 1,等等。

由於這可能會導致某些使用者感到沮喪,因此我想了解這種行為並理想地找到問題的解決方案。提前致謝。

這是由於數據類型的準確性存在一個奇怪的限制1 ,如文件所述:datetime

準確度 | 以 0.000、0.003 或 0.007 秒為增量四捨五入

解決方案是使用datetime2,它提供了更好的準確性,如您在此dbfiddle 展示中所見:

dbfiddle 中結果的螢幕截圖顯示了使用 datetime2 時的正確毫秒數

的返回類型DATEADD是動態的,取決於您發送給它的內容。因此,重要的是確保您傳遞datetime2到添加毫秒的步驟。


1 Randolph West有一個關於如何儲存 SQL Server 數據類型的精彩部落格系列,包括關於日期和時間的部落格系列(SQL Server 如何儲存數據類型:日期和時間)。該文章有來自 Data Platform MVP Jeff Moden 的有用評論:

DATETIME 的時間部分實際上是自午夜以來經過的 1/300 秒數的整數計數。這轉換為 3.3 毫秒的解析度,但該級別的解析度對於數據的儲存方式是不可能的,因此 0.0 和 3.3 毫秒向下舍入為 0 毫秒,3 毫秒和 6.6 毫秒向上舍入為 7 毫秒。

引用自:https://dba.stackexchange.com/questions/274921