BTW có rất nhiều lỗi kỹ thuật trong proc cũng như kiểu dữ liệu mà bạn đang sử dụng.
- Trong chương trình của mình, bạn có thể đặt điều kiện ngày ở đâu trong chính CTE đầu tiên.
- Nếu có thể, bạn có thể lưu trữ extrahour ở vị trí thứ hai trong bảng. Điều đó có nghĩa là Extrahours là int hoặc bigint.like -1000 hoặc 1000.varchar sẽ không bao giờ giải quyết được vấn đề của bạn.
- Việc sử dụng quá nhiều cột trong nhóm theo chính nó là cách tiếp cận sai, đặc biệt là sử dụng cột varchar trong nhóm theo. Bạn nên sử dụng cột khóa trong nhóm sau đó nối lại với bảng để lấy các cột khác trong tập kết quả.
với dữ liệu mẫu của bạn, tôi nhận được -29:-51:-30.0 thay vì -31:50:46. Hãy làm theo cách này,
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