SQL操作数数据类型datetime / varchar对求和运算符无效

时间:2018-07-13 09:52:00

标签: sql sql-server datetime sum intervals

我正在尝试从另一列中减去一列,然后对结果求和。但是,无论我如何更改,我都会不断遇到标题中提到的两个错误之一。

从发布的所有其他问题中,我得出的结论应该是:

SELECT SUM(EndTime-BeginTime) AS TotalTime FROM TimeRegister 
WHERE OrderNumber = 00000 AND Activity = 11111;

根据另一个主题的建议,我将语句更改为:

SELECT SUM(CONVERT(varchar(EndTime-BeginTime), 108)) AS TotalTime FROM TimeRegister 
WHERE OrderNumber = 00000 AND Activity = 11111;

但是,我仍然收到错误消息。 时间存储如下:

1-1-1900 7:30:00

感谢您的任何建议...


编辑1:哦,我正在通过ODBC在SQL中使用Microsoft Query for SQL,类似于: Excel vlookup incorporating SQL table


编辑2:我更喜欢再次使用HH:MM格式的输出。

问题是,当我将整个数据库复制到excel时,一切正常。我可以减去列并进行总结。我只是不想每天手动操作。...


我刚刚检查了SQL数据库,该列是日期/时间类型。

3 个答案:

答案 0 :(得分:1)

首先,尝试通过转换为文本来解决日期或数字问题永远无法解决任何问题,这会带来其他问题,例如转换失败或意外结果。

SQL Server没有时间间隔类型。如果减去两个datetime值,则会返回另一个datetime值,该值表示自1900-01-01起的偏移量之差。以下查询:

select getdate() - dateadd(d,-1,getdate())

会返回:

1900-01-02 00:00:00.000

在1900-01-01之后的整整1天。

datetime的值不能相加。 SQL Server 确实具有time类型,但这仅代表一天中的时间。即使today - yesterday有效,将其转换为time也会返回00:00

一种快速的解决方案是使用DATEDIFF以所需的任何单位(小时,分钟,秒等)计算两个日期之间的时差。请注意,尽管DATEDIFF返回了跨越的区间边界数。 DATEDIFF(DAY,...)在昨天晚上11点到今天凌晨1点之间将返回 1 ,因为超出了1天的边界。

您可以使用

SELECT sum(datediff(minute,EndTime,BeginTime)) AS TotalMinutes
FROM TimeRegister 
WHERE OrderNumber = 00000 AND Activity = 11111;

以分钟为单位计算差异并将其格式化为客户端上的时间间隔。

另一种选择是在求和之前将datetime强制转换为float,然后返回日期时间:

SELECT cast( sum(cast(EndTime - BeginTime as datetime)) as datetime) AS TotalOffset
FROM TimeRegister 
WHERE OrderNumber = 00000 AND Activity = 11111;

2天的持续时间显示为:

1900-01-03 00:00:00.000

之所以可行,是因为datetime可以强制转换为浮点数,其整数部分表示相对于1900-01-01的偏移量,而小数部分表示时间。

使用Cem语言编写的,支持间隔为 的客户端可以从中减去1900-01-01以获取实际持续时间,例如:

TimeSpan duration = sumResult - new DateTime(1900,1,1);

另一种选择是避免进行最后的强制转换,而仅将所得的float值用作天数。

在Excel中显示

最后一个选项可能是在Excel中显示持续时间的最简单方法! Excel日期实际上存储为浮点数。使它们显示为日期或时间的原因是单元格的格式。

您可以将单元格格式设置为[h]:mm:ss,以显示任何数字作为持续时间。 []很重要-没有它,Excel只会显示“日期”的时间部分。

如果您在一个单元格中输入2,则h:mm:ss将显示为0:00:00,而[h]:mm:ss将显示48:00:00(48小时)。

尽管很奇怪,

SELECT sum(cast(EndTime - BeginTime as datetime)) AS TotalDuration
FROM TimeRegister 
WHERE OrderNumber = 00000 AND Activity = 11111;

可能是在Excel中显示持续时间总和的最佳选择

答案 1 :(得分:0)

以下内容如何:

WITH totalTime AS (
  SELECT SUM(DATEDIFF(second,  EndTime, BeginTime)) as TimeInSecond
  FROM TimeRegister 
  WHERE OrderNumber = 00000 AND Activity = 11111;
)
SELECT RIGHT('0' + CAST(TimeinSecond / 3600 AS VARCHAR),2) + ':' +
  RIGHT('0' + CAST((TimeinSecond / 60) % 60 AS VARCHAR),2) + ':' +
  RIGHT('0' + CAST(TimeinSecond % 60 AS VARCHAR),2) AS TimeElapsed
FROM totalTime;

在此解决方案中,时间在总计之前先转换为秒,然后转换为HH:MM:SS。

答案 2 :(得分:0)

您似乎想要datediff()

SELECT SUM(DATEDIFF(second, BeginTime, EndTime) AS TotalTime
FROM TimeRegister 
WHERE OrderNumber = 00000 AND Activity = 11111;