Sql 超过24小时的总日期时间
有没有办法把datetime加起来,总数就超过24小时 这是我的脚本,通话时间存储为varcharSql 超过24小时的总日期时间,sql,sql-server,Sql,Sql Server,有没有办法把datetime加起来,总数就超过24小时 这是我的脚本,通话时间存储为varchar select cast(sum(cast(left(right(convert(char(19),cast(talkTime as datetime),120),8),2) as int)+ (cast(left(right(convert(char(19),cast(talkTime as datetime),120),5),2) as real)/60)+ (cast(left(right(
select
cast(sum(cast(left(right(convert(char(19),cast(talkTime as datetime),120),8),2) as int)+
(cast(left(right(convert(char(19),cast(talkTime as datetime),120),5),2) as real)/60)+
(cast(left(right(convert(char(19),cast(talkTime as datetime),120),2),2) as real)/3600)) as datetime)
from table1
这是我试图总结的数据
talkTime
0:45:43
4:19:42
4:21:19
5:52:29
4:59:25
6:06:21
5:03:00
5:51:24
5:18:35
总数应为。42:37:58. 但我得到的却是这个。1900-02-12 15:11:12.047. 我读到这是因为sql只能在datetime上存储24小时。是否有一种变通方法可用于获得所需的输出?将持续时间存储在datetime中,但使用时将DATEDIFF()与“1900-01-01”一起存储
DECLARE @StartTime datetime = '2015-01-19 17:18', @EndTime datetime = GETDATE()
SELECT
@StartTime AS StartTime,
@EndTime AS EndTime,
@EndTime - @StartTime AS Duration,
DATEDIFF(DAY, '1900-01-01', @EndTime - @StartTime) AS Day,
DATEDIFF(HOUR, '1900-01-01', @EndTime - @StartTime) % 24 AS Hour,
DATEDIFF(MINUTE, '1900-01-01', @EndTime - @StartTime) % 60 AS Minute,
DATEDIFF(SECOND, '1900-01-01', @EndTime - @StartTime) % 60 AS Second,
RIGHT(CONVERT(varchar(20), @EndTime - @StartTime, 120), 8) AS Time
结果
如果您只是想得到两个日期时间值之间的持续时间,可以使用简单的
DATEDIFF
计算。这是一种相当冗长的方法,如果要使用它,您最好在函数中修改并保留它:
MS SQL Server架构设置:
CREATE TABLE TalkTime
([talkTime] time(4))
;
INSERT INTO TalkTime
([talkTime])
VALUES
('0:45:43'),
('4:19:42'),
('4:21:19'),
('5:52:29'),
('4:59:25'),
('6:06:21'),
('5:03:00'),
('5:51:24'),
('5:18:35')
;
DECLARE @hours INT
DECLARE @mins INT
DECLARE @secs INT
SELECT @hours = SUM(DATEDIFF(HOUR, '0:00:00', talktime)) +
((SUM(DATEDIFF(minute, '0:00:00', talktime)) - (SUM(DATEDIFF(hour, '0:00:00', talktime)) *60)) / 60)
FROM TalkTime
SELECT @mins = (SUM(DATEDIFF(SECOND, '0:00:00', talktime)) - (@hours*60*60))/60
FROM TalkTime
SELECT @secs = (SUM(DATEDIFF(SECOND, '0:00:00', talktime))) - ((@hours*60*60) + (@mins*60))
FROM TalkTime
SELECT CAST(@hours AS NVARCHAR(4)) + ':' + CAST(@mins AS NVARCHAR(2)) + ':' + CAST(@secs AS NVARCHAR(2))
| COLUMN_0 |
|----------|
| 42:37:58 |
分隔时间段并返回字符串表示形式:
CREATE TABLE TalkTime
([talkTime] time(4))
;
INSERT INTO TalkTime
([talkTime])
VALUES
('0:45:43'),
('4:19:42'),
('4:21:19'),
('5:52:29'),
('4:59:25'),
('6:06:21'),
('5:03:00'),
('5:51:24'),
('5:18:35')
;
DECLARE @hours INT
DECLARE @mins INT
DECLARE @secs INT
SELECT @hours = SUM(DATEDIFF(HOUR, '0:00:00', talktime)) +
((SUM(DATEDIFF(minute, '0:00:00', talktime)) - (SUM(DATEDIFF(hour, '0:00:00', talktime)) *60)) / 60)
FROM TalkTime
SELECT @mins = (SUM(DATEDIFF(SECOND, '0:00:00', talktime)) - (@hours*60*60))/60
FROM TalkTime
SELECT @secs = (SUM(DATEDIFF(SECOND, '0:00:00', talktime))) - ((@hours*60*60) + (@mins*60))
FROM TalkTime
SELECT CAST(@hours AS NVARCHAR(4)) + ':' + CAST(@mins AS NVARCHAR(2)) + ':' + CAST(@secs AS NVARCHAR(2))
| COLUMN_0 |
|----------|
| 42:37:58 |
:
CREATE TABLE TalkTime
([talkTime] time(4))
;
INSERT INTO TalkTime
([talkTime])
VALUES
('0:45:43'),
('4:19:42'),
('4:21:19'),
('5:52:29'),
('4:59:25'),
('6:06:21'),
('5:03:00'),
('5:51:24'),
('5:18:35')
;
DECLARE @hours INT
DECLARE @mins INT
DECLARE @secs INT
SELECT @hours = SUM(DATEDIFF(HOUR, '0:00:00', talktime)) +
((SUM(DATEDIFF(minute, '0:00:00', talktime)) - (SUM(DATEDIFF(hour, '0:00:00', talktime)) *60)) / 60)
FROM TalkTime
SELECT @mins = (SUM(DATEDIFF(SECOND, '0:00:00', talktime)) - (@hours*60*60))/60
FROM TalkTime
SELECT @secs = (SUM(DATEDIFF(SECOND, '0:00:00', talktime))) - ((@hours*60*60) + (@mins*60))
FROM TalkTime
SELECT CAST(@hours AS NVARCHAR(4)) + ':' + CAST(@mins AS NVARCHAR(2)) + ':' + CAST(@secs AS NVARCHAR(2))
| COLUMN_0 |
|----------|
| 42:37:58 |
您需要将varchar转换为时间,然后使用
DATEDIFF
将时间转换为秒,然后才能对其进行汇总:
SELECT Seconds = SUM(DATEDIFF(SECOND, '00:00', CAST(Duration AS TIME)))
FROM T;
然后,您可以使用各种转换将结果返回到VARCHAR
,尽管我建议您最好在表示层中执行此转换:
CREATE TABLE #T (Duration varchar(7));
INSERT INTO #T (Duration)
VALUES
('0:45:43'), ('4:19:42'), ('4:21:19'), ('5:52:29'), ('4:59:25'),
('6:06:21'), ('5:03:00'), ('5:51:24'), ('5:18:35');
SELECT Formatted = STUFF(CONVERT(VARCHAR(8), DATEADD(SECOND, Seconds, 0), 108),
1, 2, CAST(FLOOR(Seconds / 3600) AS VARCHAR(5)))
FROM ( SELECT Seconds = SUM(DATEDIFF(SECOND, '00:00', CAST(Duration AS TIME)))
FROM #T
) AS s;
此处的格式设置执行以下操作:
DATETIME
-DATEADD(秒,秒,0),108)
VARCHAR
,格式为hh:mm:ss
-Convert(VARCHAR(8),[DATETIME]),108)
李>
VARCHAR
-CAST(地板(秒/3600)为VARCHAR(5))
STUFF
将这些小时以hh:mm:ss
的格式插入字符串中,以代替hh
ALTER TABLE T ADD DurationInSeconds AS DATEDIFF(SECOND, '00:00', CAST(Duration AS TIME));
您可以将格式化逻辑放在它自己的函数中:
CREATE FUNCTION [dbo].[GetFormattedDuration] (@Second DECIMAL(15, 2))
RETURNS TABLE
AS
RETURN
(
SELECT FormattedDuration = CASE WHEN @Second < 86400 THEN CONVERT(VARCHAR(8), DATEADD(MILLISECOND, (@second * 1000), '00:00:00.000'), 108)
ELSE STUFF(CONVERT(VARCHAR(8), DATEADD(MILLISECOND, (@second * 1000), '00:00:00.000'), 108), 1, 2, CAST(FLOOR(@Second / 3600) AS VARCHAR(5)))
END
);
我使用内联表值函数纯粹是出于性能原因尝试以下方法:
SELECT
cast(datediff(hour, 0,
dateadd(s, sum(datediff(second, 0, talktime)), 0)) as varchar(5))
+ right(convert(char(19),dateadd(s, sum(datediff(second, 0, talktime)),0), 126), 6)
FROM
(values(cast('12:55:02' as time)),
(cast('13:55' as time))) table1(talktime)
结果:
26:50:02
用表1替换最后2个示例行日期值的格式和类型是什么?那么,您希望您的输出是什么?您能提供一些示例数据和所需的输出吗?对于持续时间来说,时间或日期时间不是一个好的选择。持续时间应存储为十进制/整数,例如,不存储
hh:mm:ss
,只存储经过的秒数。所以01:02:03
变成了3723
。如果您想在演示层中以hh:mm:ss
格式显示3723,请担心这个问题。@garethdate-time是存储持续时间的好方法,您可以正常添加它们,并在不计算的情况下请求不同的部分。Duration=enddatetime-startdatetime,但不能在上直接使用聚合datetimes@t-克劳森:不是。您如何将25小时30分钟存储为约会时间?如果开始时间是相关的,我同意如果开始时间是相关的,那么将开始和结束日期存储为日期时间是最好的方法,但是对于任意的持续时间,它应该是decimal/int.Hi。我要做的是添加datetime字段。结果将超过24小时。@ElishTorres这里有一个更新的答案,其中有一些相当丑陋的计算,可能会帮助你我自己明白了我要做什么。无论如何,谢谢。:)这是MsSQL。我犯了个错误“秒到秒时间”不是可识别的函数名TIME_TO_SEC'不是一个可识别的函数名。对不起,我将您的评论误读为“对不起,这是MySQL”,而不是“MsSQL”-我会编辑我自己知道我在做什么。无论如何,谢谢。:)