Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Retornar mais de 24 horas no formato hh:mm:ss no SQL Server 2008


BTW existem tantas falhas técnicas no proc, bem como no tipo de dados que você está usando. O problema real está aqui.
  1. No seu proc, você pode colocar where date condition no primeiro CTE.
  2. Se possível, você pode armazenar horas extras em segundos na tabela. Isso significa que horas extras são int ou bigint.like -1000 ou 1000.varchar nunca resolverá seu problema. Isso evitará muitas conversões, portanto, rápido.
  3. Usar tantas colunas em group by é uma abordagem errada. Especialmente usar a coluna varchar em group by. Você deve usar a coluna chave no grupo e, em seguida, unir novamente com a tabela para obter outras colunas no conjunto de resultados.

com seus dados de amostra estou obtendo -29:-51:-30.0 em vez de -31:50:46 .faça desta forma,
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