Usuário com melhor resposta
Somar horas e minutos coluna Time(7)

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
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
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
-
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
-
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