none
Somar horas e minutos coluna Time(7) RRS feed

  • Pergunta

  • Pessoal,

    Estou quebrando a cabeça em um calculo de horas em um sistema que gerencia horas extras e faltas, tenho no banco salvo a quantidade de horas e minutos em uma coluna Time(7).

    E estou usando a seguinte querye para fazer a somatória:

    SELECT        DP.TeacherHour.ClassificationID, DP.TeacherHour.Year, DP.TeacherHour.Month, 
    DP.TeacherHour.SubstituteBaseID, DP.TeacherHour.SubstituteID,
    (SELECT [Professor] FROM [DP].[v_Teachers] WHERE cod_funcionario = DP.TeacherHour.SubstituteID) AS Teacher,
    (SELECT Description FROM DP.TeacherBase WHERE TeacherBaseID = DP.TeacherHour.SubstituteBaseID )AS Base,
     SUM(DP.TeacherHour.Classes) AS Classes, 
     (SELECT CASE
     WHEN
      SUM(DATEDIFF(MINUTE, '0:00:00', DP.TeacherHour.Intime)) IS NULL THEN  '0'
      ELSE SUM(DATEDIFF(MINUTE, '0:00:00', DP.TeacherHour.Intime)) END ) /60 AS Intime,
     --SUM(Dp.TeacherHour.Intime) AS inTime,
     (SELECT code FROM [DP].[TeacherBasePay] WHERE TeacherBaseID = DP.TeacherHour.SubstituteBaseID AND TypeHourID = DP.TeacherHour.Type ) AS Verba,
      DP.TeacherHour.Type
    FROM            DP.TeacherHour INNER JOIN
                             DP.TeacherHourAproved ON DP.TeacherHour.SiteID = DP.TeacherHourAproved.SiteID AND DP.TeacherHour.ClassificationID = DP.TeacherHourAproved.ClassificationID AND 
                             DP.TeacherHour.TeacherHourID = DP.TeacherHourAproved.TeacherHourID
    WHERE        (DP.TeacherHourAproved.Aproved = 1)
    GROUP BY DP.TeacherHour.ClassificationID, DP.TeacherHour.Year, 
    DP.TeacherHour.Month, DP.TeacherHour.SubstituteBaseID,  DP.TeacherHour.SubstituteID, DP.TeacherHour.Type
    HAVING        (DP.TeacherHour.Year = 2019) AND (DP.TeacherHour.Month = 09) AND (DP.TeacherHour.Type = 2)
    

    Desataco o calculo das horas:

     (SELECT CASE
     WHEN
      SUM(DATEDIFF(MINUTE, '0:00:00', DP.TeacherHour.Intime)) IS NULL THEN  '0'
      ELSE SUM(DATEDIFF(MINUTE, '0:00:00', DP.TeacherHour.Intime)) END ) /60 AS Intime,

    Esta calculando somente as horas e os minutos quebrados não está me trazendo, exemplo(58 horas e 30 minutos seria 58:30 ele esta me retornando apenas 58)

    Devo estar fazendo algo errado no calculo ou na conversão, alguém tem alguma ideia onde estou errando?

    Obrigado.


    Moizés Cerqueira | MCP / MCTS SQL SERVER

    segunda-feira, 16 de setembro de 2019 18:24

Respostas

  • Esta calculando somente as horas e os minutos quebrados não está me trazendo, exemplo(58 horas e 30 minutos seria 58:30 ele esta me retornando apenas 58)

    Olá Moizés.

    58h30 é o mesmo que 3.510 minutos. Ao efetuar a divisão inteira de 3.510 minutos por 60 o que se obtém é 58. Qual valor que você esperava no resultado?

    Se o objetivo é obter horário decimal, então altere o divisor para "60.0".

    -- código #1
    PRINT 3510 / 60;
    PRINT 3510 / 60.0;
     


    José Diz     Belo Horizonte, MG - Brasil     [query performance tuning: Porto SQL]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    • Marcado como Resposta Moizés Cerqueira segunda-feira, 16 de setembro de 2019 22:53
    • Editado José Diz segunda-feira, 16 de setembro de 2019 22:57
    segunda-feira, 16 de setembro de 2019 18:49

Todas as Respostas

  • Esta calculando somente as horas e os minutos quebrados não está me trazendo, exemplo(58 horas e 30 minutos seria 58:30 ele esta me retornando apenas 58)

    Olá Moizés.

    58h30 é o mesmo que 3.510 minutos. Ao efetuar a divisão inteira de 3.510 minutos por 60 o que se obtém é 58. Qual valor que você esperava no resultado?

    Se o objetivo é obter horário decimal, então altere o divisor para "60.0".

    -- código #1
    PRINT 3510 / 60;
    PRINT 3510 / 60.0;
     


    José Diz     Belo Horizonte, MG - Brasil     [query performance tuning: Porto SQL]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    • Marcado como Resposta Moizés Cerqueira segunda-feira, 16 de setembro de 2019 22:53
    • Editado José Diz segunda-feira, 16 de setembro de 2019 22:57
    segunda-feira, 16 de setembro de 2019 18:49
  • Usei detsa forma que vc disse e traz o resta da divisão em decimal mas vou tratar melhor no C#.

      SUM(DATEDIFF(MINUTE, '0:00:00', DP.TeacherHour.Intime)) IS NULL THEN  ' '
      ELSE SUM(DATEDIFF(MINUTE, '0:00:00', DP.TeacherHour.Intime))/60.0 END )  AS Intime,
    Resultado

    Obrigado.


    Moizés Cerqueira | MCP / MCTS SQL SERVER

    segunda-feira, 16 de setembro de 2019 22:57
  • Usei desta forma que vc disse e traz o resta da divisão em decimal mas vou tratar melhor no C#.

    Ao transformar hh:mm:ss em minutos, usando a função DATEDIFF(), o contexto sai de sexagesimal para decimal; Por isso que 30 minutos saiu como 0.50, isto é, meia hora.

    O tipo de dados time(7) somente aceita até 23:59:59.9999999.

    ---

    O trecho de código

    cast ((sum (datediff (second, 0, DP.TeacherHour.Intime)) / 3600) as varchar(5))
    + right (cast (dateadd (second, sum (datediff (second, 0, DP.TeacherHour.Intime)), 0) as time(0)), 6)

    retorna o que você quer, mas acho que ficou complicado...

    Considerando-se que 58h30min é o mesmo que 210.600 segundos, o que o trecho de código acima faz é algo como
        SELECT cast ((210600 / 3600) as varchar(5))
           + right (cast (dateadd (second, 210600, 0) as time(0)), 6);

     


    José Diz     Belo Horizonte, MG - Brasil     [query performance tuning: Porto SQL]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    • Editado José Diz terça-feira, 17 de setembro de 2019 13:02
    segunda-feira, 16 de setembro de 2019 23:44