这是因为DATEDIFF()函数返回一个整数。整数只允许最大为 2,147,483,647 的值。在这种情况下,您有超过 ~2B 的值导致数据类型溢出。理想情况下,您会使用DATEDIFF_BIG()函数,该函数返回一个bigint,允许值高达 9,223,372,036,854,775,807 或 ~9 Septillion。SQL 数据仓库/Azure Synapse Analytics(截至 2020 年 1 月)不支持 DATEDIFF_BIG()。
您可以在此处为该功能投票:(https://feedback.azure.com/forums/307516/suggestions/14781627)
测试 DATEDIFF(),您可以看到在用完整数之前,您可以在日期之间获得约 25 天和 20 小时的差异。一些示例代码如下。
DECLARE @startdate DATETIME2 = '01/01/2020 00:00:00.0000';
DECLARE @enddate DATETIME2 = '01/01/2020 00:00:02.0000';
-- Support:
-- MILLISECOND: ~25 days 20 Hours
-- MICROSECOND: ~35 minutes
-- NANOSECOND: ~ 2 seconds
SELECT
DATEDIFF(DAY, @startdate, @enddate) [day]
, DATEDIFF(HOUR, @startdate, @enddate) [hour]
, DATEDIFF(MINUTE, @startdate, @enddate) [minute]
, DATEDIFF(SECOND, @startdate, @enddate) [second]
, DATEDIFF(MILLISECOND, @startdate, @enddate) [millisecond]
, DATEDIFF(MICROSECOND, @startdate, @enddate) [microsecond]
, DATEDIFF(NANOSECOND, @startdate, @enddate) [nanosecond]
在此期间,您可以计算每个值自时间开始以来的刻度,然后减去差值。对于 DATETIME2,您可以像这样计算刻度:
CREATE FUNCTION dbo.DATEDIFF_TICKS(@date DATETIME2)
RETURNS BIGINT
AS
BEGIN
RETURN
(DATEDIFF(DAY, '01/01/0001', CAST(@date AS DATE)) * 864000000000.0)
+ (DATEDIFF(SECOND, '00:00', CAST(@date AS TIME(7))) * 10000000.0)
+ (DATEPART(NANOSECOND, @date) / 100.0);
END
GO
然后,您可以运行该函数并确定刻度和刻度之间的差异。
DECLARE @startdate DATETIME2 = '01/01/2020 00:00:00.0000';
DECLARE @enddate DATETIME2 = '01/30/2020 00:00:00.0000';
SELECT
dbo.DATEDIFF_TICKS(@startdate) [start_ticks],
dbo.DATEDIFF_TICKS(@startdate) [end_ticks],
dbo.DATEDIFF_TICKS(@enddate) - dbo.DATEDIFF_TICKS(@startdate) [diff];
这是一个运行 500 年差异的示例:
DECLARE @startdate DATETIME2 = '01/01/2000 00:00:00.0000';
DECLARE @enddate DATETIME2 = '01/01/2500 00:00:00.0000';
SELECT
dbo.DATEDIFF_TICKS(@startdate) [start_ticks],
dbo.DATEDIFF_TICKS(@startdate) [end_ticks],
dbo.DATEDIFF_TICKS(@enddate) - dbo.DATEDIFF_TICKS(@startdate) [diff];
结果:
start_ticks end_ticks diff
-------------------- -------------------- --------------------
630822816000000000 630822816000000000 157785408000000000