Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Retourne plus de 24 heures au format hh:mm:ss dans SQL Server 2008

BTW il y a tellement de défauts techniques dans proc ainsi que le type de données que vous utilisez. Le vrai problème est ici.

  1. Dans votre proc, vous pouvez mettre la condition de date où en premier CTE lui-même.
  2. Si possible, vous pouvez stocker extrahour en seconde dans le tableau. Cela signifie que Extrahours est int ou bigint.like -1000 ou 1000.varchar ne résoudra jamais votre problème. Cela vous évitera beaucoup de conversions, donc rapidement.
  3. L'utilisation d'autant de colonnes dans le groupe par est en soi une mauvaise approche. En particulier, l'utilisation de la colonne varchar dans le groupe par. Vous devez utiliser la colonne clé dans le groupe par, puis rejoignez la table pour obtenir d'autres colonnes dans le jeu de résultats.

avec vos exemples de données, j'obtiens -29:-51:-30.0 au lieu de -31:50:46 .faites-le de cette façon,

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