Между другото има толкова много технически пропуски в proc, както и в типа данни, които използвате. Истинският проблем е тук.
- Във вашата процедура можете да поставите къде условие за дата в самия първи CTE.
- Ако е възможно, можете да съхранявате extrahours във секунда в таблицата. Това означава, че Extrahours е int или bigint.like -1000 или 1000.varchar никога няма да реши проблема ви. Ще ви спести много преобразуване, следователно бързо.
- Използването на толкова много колони в групиране по само по себе си е грешен подход. Особено използването на колона varchar в групиране по. Трябва да използвате ключова колона в групата, след което отново да се присъедините към таблицата, за да получите други колони в набора от резултати.
с вашите примерни данни получавам -29:-51:-30.0 вместо -31:50:46 .направете го по този начин,
DECLARE @t TABLE (ExtraHrs VARCHAR(20))
INSERT INTO @t
VALUES ('00:59:38')
,('-03:59:37')
,('-08:59:39')
,('-08:52:36')
,('-08:59:16');
WITH cte
AS (
SELECT ExtraHrs
,CASE
WHEN left(ExtraHrs, 1) = '-'
THEN - 1
ELSE 1
END AS multiply
,right(ExtraHrs, 8) AS timestring
,
--get hours in seconds:
DATEPART(HOUR, right(ExtraHrs, 8)) * 3600 AS h_in_s
,
--get minutes in seconds:
DATEPART(MINUTE, right(ExtraHrs, 8)) * 60 AS m_in_s
,
--get seconds:
DATEPART(SECOND, right(ExtraHrs, 8)) AS s
FROM @t
)
,CTE3
AS (
SELECT *
,c.h_in_s + c.m_in_s + c.s AddExtra
FROM cte c
)
,cte4
AS (
SELECT sum(AddExtra * multiply) mn
FROM cte3
)
,cte5
AS (
SELECT mn / 3600 hh
,(mn % 3600) / 60 mi
,(mn % 3600.0) % 60 ss
FROM cte4
)
SELECT CASE
WHEN hh < 0
THEN '-'
ELSE ''
END
,cast(hh AS VARCHAR) + ':' + cast(mi AS VARCHAR) + ':' + cast(ss AS VARCHAR)
FROM cte5