我正在尝试从另一列中减去一列,然后对结果求和。但是,无论我如何更改,我都会不断遇到标题中提到的两个错误之一。
从发布的所有其他问题中,我得出的结论应该是:
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数据库,该列是日期/时间类型。
答案 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;