Sql-Server
帶有毫秒的 DATEADD 和 DATEPART 會產生奇怪的結果
我有一個表格,其中包含 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 展示中所見:的返回類型
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 毫秒。