sql >> Base de Datos >  >> RDS >> Sqlserver

Devuelve más de 24 horas en formato hh:mm:ss en el servidor SQL 2008

Por cierto, hay tantos defectos técnicos en el proceso como en el tipo de datos que está utilizando. El problema real está aquí.

  1. En su proceso, puede poner la condición de fecha en el primer CTE.
  2. Si es posible, puede almacenar extrahour en segundos en la tabla. Eso significa que Extrahours es int o bigint.like -1000 o 1000.varchar nunca resolverá su problema. Le ahorrará muchas conversiones, por lo tanto, rápido.
  3. Usar tantas columnas en el grupo es en sí mismo un enfoque incorrecto. Especialmente usar la columna varchar en el grupo. Debe usar la columna clave en el grupo y luego unirse nuevamente con la tabla para obtener otras columnas en el conjunto de resultados.

con sus datos de muestra obtengo -29:-51:-30.0 en lugar de -31:50:46. Hágalo de esta manera,

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