SQL DATEDIFF结果与Excel的区别在于小时数

时间:2018-11-28 07:58:09

标签: sql sql-server excel

努力寻找解决此问题的方法。

我们正在远离excel,并通过减去两个日期在数小时内将计算结果添加到SQL中。

问题在于我们在excel中的结果不同于SQL。

这是我们在excel中的功能:

Change Date: 30/10/2018      
Change Time: 10:53

Service Date: 29/10/2018    
Service Time: 9:37      

The Formula in excel is: =((Change Date+Change Time)-(Service Date+Service Time))*24

小时数的结果是: 25.26666667

使用DATEDIFF(下面的语法)将相同的数据导入SQL:

datediff(second,CAST(CAST(CONVERT(DATETIME,Service_Date,103) as smalldatetime) 
            + CAST(CONVERT(DATETIME,Service_Time,103) as smalldatetime) as smalldatetime),
            CAST(CAST(CONVERT(DATETIME,Change_Date,103) as smalldatetime) 
            + CAST(CONVERT(DATETIME,Change_Time,103) as smalldatetime) as smalldatetime)) /3600.0

给出结果: 26.350000

有人对解决这种差异有想法吗?

先感谢堆,

朱莉安娜

2 个答案:

答案 0 :(得分:0)

服务器级别的归类可以终止任何计算,这就是为什么要确保所使用的服务器不被更改的原因,以确保您100%确保将string dates and times完全转换为SQL Server datetime

根据您的示例,我假设您使用的是正则格式,因此,您可以尝试执行以下操作:

DECLARE @ExcelDate1 CHAR(10) = '30/10/2018'
DECLARE @ExcelTime1 CHAR(5) = '10:53'

DECLARE @ExcelDate2 CHAR(10) = '29/10/2018'
DECLARE @ExcelTime2 CHAR(5) = '09:37'

--> make sure that whatever server collation you use you will get a right date format:
DECLARE @ExcelDateTime1 datetime = DATETIMEFROMPARTS(CAST(RIGHT(@ExcelDate1,4) as int), CAST(SUBSTRING(@ExcelDate1,4,2) as int), CAST(LEFT(@ExcelDate1,2) as int), CAST(LEFT(@ExcelTime1,2) as int), CAST(RIGHT(@ExcelTime1,2) as int), 0, 0);
DECLARE @ExcelDateTime2 datetime = DATETIMEFROMPARTS(CAST(RIGHT(@ExcelDate2,4) as int), CAST(SUBSTRING(@ExcelDate2,4,2) as int), CAST(LEFT(@ExcelDate2,2) as int), CAST(LEFT(@ExcelTime2,2) as int), CAST(RIGHT(@ExcelTime2,2) as int), 0, 0);

SELECT ABS(DATEDIFF(mi, @ExcelDateTime1, @ExcelDateTime2) / 60.0);
  

结果:25.266666

要获取 7 作为最后一位数字,您可以使用ROUND()函数。

答案 1 :(得分:0)

检查您的输入。您的逻辑是正确的,尽管可以简化。为了清楚起见,请在SSMS中运行以下代码示例。

declare @Service_Date varchar(max) = '30/10/2018'
declare @Service_Time varchar(max) = '10:53'

declare @Change_Date varchar(max) = '29/10/2018'
declare @Change_Time varchar(max) = '9:37'

--
-- Original 
--
select datediff(second,CAST(CAST(CONVERT(DATETIME,@Service_Date,103) as smalldatetime) 
            + CAST(CONVERT(DATETIME,@Service_Time,103) as smalldatetime) as smalldatetime),
            CAST(CAST(CONVERT(DATETIME,@Change_Date,103) as smalldatetime) 
            + CAST(CONVERT(DATETIME,@Change_Time,103) as smalldatetime) as smalldatetime)) /3600.0

--
-- Simplified - same result
--
select datediff(second,
    (CONVERT(smalldatetime,@Service_Date,103) + CONVERT(smalldatetime,@Service_Time,103)),
    (CONVERT(smalldatetime,@Change_Date,103) + CONVERT(smalldatetime,@Change_Time,103))) /3600.0

--
-- Simplfied - shows error is with inpuyts, not logic
--
set @Service_Time = '11:57'
set @Change_Time = '9:36'
select datediff(second,
    (CONVERT(smalldatetime,@Service_Date,103) + CONVERT(smalldatetime,@Service_Time,103)),
    (CONVERT(smalldatetime,@Change_Date,103) + CONVERT(smalldatetime,@Change_Time,103))) /3600.0