预期结果为3201:20。我已经用“:”分割了。请提出实现此目标的最佳方法。
DECLARE @tmpTime TABLE
(
RowId INT IDENTITY(1, 1),
EmployeeId INT,
TotalWorkingTime NVARCHAR(10)
);
INSERT INTO @tmpTime
(
EmployeeId, TotalWorkingTime
)
VALUES
(1,N'1500:30'),
(2,N'1700:50');
SELECT SUM(TotalWorkingTime) FROM @tmpTime
答案 0 :(得分:3)
SQL Server不会关闭超过24小时的时间类型。因此,不要以time
的方式考虑您的工作。它只是数字的时髦字符串表示形式。
因此,您可以将值解析为数字,进行求和,然后重建值:
select (cast(sum(hh) + sum(mm) / 60 as varchar(255)) + ':' +
right('00' + cast(sum(mm) % 60 as varchar(255)), 2)
) as hhmm
from ( VALUES (1,N'1500:30'), (2,N'1700:50') ) t(EmployeeId, TotalWorkingTime) cross apply
(values (cast(left(TotalWorkingTime, charindex(':', TotalWorkingTime) - 1) as int),
cast(stuff(TotalWorkingTime, 1, charindex(':', TotalWorkingTime), '') as int)
)
) v(hh, mm)
答案 1 :(得分:1)
从@GordonLinoff的答案可以看出,使用VARCHAR
表示真正的持续时间时,查询非常复杂。如果您以更自然的方式表示数据,则查询会变得更加简单。例如,如果您将工作时间存储为整数(总分钟),则可以使用中间CTE和几个CROSS APPLY
来获得所需的内容:
-- note that TotalWorkingTime is now TotalWorkingTimeMinutes
DECLARE @tmpTime TABLE
(
RowID INT IDENTITY(1,1),
EmployeeID INT,
TotalWorkingTimeMinutes INT
);
-- while I'm using a calculation to show
-- how the minutes get added, this would likely
-- be done by the application, before it gets
-- sent to the database.
INSERT INTO @tmpTime
(EmployeeID, TotalWorkingTimeMinutes)
VALUES
(1, (1500 * 60) + 30),
(2, (1700 * 60) + 50);
-- I think this intermediate CTE makes things a bit clearer.
-- but of course, you can inline it as well.
WITH SummedMinutesWorked(SummedMinutes) AS
(
SELECT SUM(TotalWorkingTimeMinutes)
FROM @tmpTime
)
-- you can use the CROSS APPLY to get the hours,
-- then reference those to get the "remainder minutes"
-- the SELECT has to cast your hours and minutes to a VARCHAR
-- for concatenation
SELECT CAST(H AS VARCHAR(255)) + ':' + CAST(M AS VARCHAR(255))
FROM SummedMinutesWorked
CROSS APPLY (SELECT SummedMinutes / 60 AS H) AS HoursWorked
CROSS APPLY (SELECT SummedMinutes - (H * 60) AS M) AS RemainderMinutes
答案 2 :(得分:0)
您可以尝试使用left()和right()函数在':'之前和之后查找字符
select
concat
(
sum(cast(left(TotalWorkingTime,CHARINDEX(':',TotalWorkingTime)-1) as int)),
':',
case when sum(cast(right(TotalWorkingTime,CHARINDEX(':',TotalWorkingTime)-3) as int))>60 then sum(cast(right(TotalWorkingTime,CHARINDEX(':',TotalWorkingTime)-3) as int))-60 else sum(cast(right(TotalWorkingTime,CHARINDEX(':',TotalWorkingTime)-3) as int)) end
) FROM @tmpTime