2013-07-08 3 views
1

Я вычислительное TotalHours из сотрудника работал в офисе на основе Intime и Outtime равнодействующей в виде hh.mm как 8.30.функция SQL DateDiff привело к переполнению

Итак, я написал ниже SQL-запрос:

SELECT EMPLOYEEID, sum(DateDiff(mi,isnull(In_Time,0),isnull(Out_Time,0))/60) + 
sum(round(DateDiff(mi,isnull(In_Time,0),isnull(Out_Time,0))%60,2))/100.0 + 
sum(round(DateDiff(ss,isnull(In_Time,0),isnull(Out_Time,0)),2))/10000.0 as 
TotalHours from HR_EMPLOYEES 

Этот запрос SQL Server правильно работает intially, но теперь она дает следующее исключение:

java.sql.SQLException: The datediff function resulted in an overflow. The number of 
dateparts separating two date/time instances is too large. Try to use datediff with a 
less precise datepart. 

Может кто-нибудь, пожалуйста, помогите мне избавиться от этого?

+0

По какой-либо причине вы не можете просто использовать 'DateDiff' с опцией часов вместо всех этих формул? Я также ставлю, что, поскольку вы проверяете нулевые значения, вы получаете минимальную дату назад - и, поскольку вы запрашиваете секунды, это то, что переполнено – Charleh

+0

Возможно, вы хотите просто вернуть 0 для нулевой даты вместо – Charleh

+0

, если возможно, я хочу вернуться время 7:00 PM для нулевой даты вместо – User12345

ответ

1

Вы можете попробовать это:

select empid, 
convert(varchar(5), sum(datediff(minute, [intime], isnull([outtime], dateadd(hh, 19, DATEADD(dd, DATEDIFF(dd, 0, [intime]), 0)))))/60) 
+ ':' + 
convert(varchar(5),sum(datediff(minute, [intime], isnull([outtime], dateadd(hh, 19, DATEADD(dd, DATEDIFF(dd, 0, [intime]), 0))))) % 60) 
as TotalHours 
from HR_EMPLOYEES group by empid 

Некоторые мысли:

  1. Может intime когда-либо быть пустым? Если да, то как и почему? Я предполагаю, что intime никогда не может быть пустым
  2. Я предполагаю, что если outtime является null тогда, работник продолжает работать, таким образом, использование getdate() Но это также может быть так, что была ошибка программного обеспечения, которое вызвало null.
  3. Другая стратегия для обработки null в outtime может быть выполнена в полночь intime. Тогда это задает вопрос, как будет обрабатываться следующий день.

Думаю, здесь может быть много краевых случаев. Вы должны быть осторожны.

РЕДАКТИРОВАТЬ: Изменено outtime до 7 вечера intime день, если outtime имеет значение NULL согласно комментарию OP. Used Best approach to remove time part of datetime in SQL Server

+0

Да, вы правы, intime не будет иметь значение null, и время ожидания может быть нулевым, так что есть ли способ, которым я могу заполнить время работы с постоянным временем, предположим, что 7:00 вечера в вышеуказанном запросе. спасибо – User12345

+0

Внесли изменения в код sql, посмотрите, работает ли он. Я его не тестировал. – unlimit

+0

Привет, спасибо, над запросом работает, но для некоторого сотрудника, минуты не отображаются в общем количестве часов, например (10:22, но отображается только 10: в основном, когда общее количество часов превышает более 10 часов), может, пожалуйста, дать представление как сделать его правильным. – User12345

0

Вместо того, чтобы использовать 0 как по умолчанию/фиксированную точку во времени, вместо этого используйте другую постоянную дату, которая ближе к значениям, которые вы собираетесь обрабатывать, и, следовательно, с меньшей вероятностью приведет к переполнению.

0 моментально конвертируется в полночь 01/01/1900. Лучше константа может быть, например, 01.01.2000:

SELECT EMPLOYEEID, sum(DateDiff(mi,isnull(In_Time,'20000101'),isnull(Out_Time,'20000101'))/60) + 
sum(round(DateDiff(mi,isnull(In_Time,'20000101'),isnull(Out_Time,'20000101'))%60,2))/100.0 + 
sum(round(DateDiff(ss,isnull(In_Time,'20000101'),isnull(Out_Time,'20000101')),2))/10000.0 as 
TotalHours from HR_EMPLOYEES 

Хотя больше я смотрю на это, тем больше я не уверен, что недобросовестный дату на любое значение, даже имеет смысл.

+0

Согласился на бит «смысл» - казалось бы, если у них нет времени на входе/выходе, то отработанные часы не могут быть рассчитаны (я работал на этой неделе в течение 17 тысяч часов;)) – Charleh

+0

@Damien: спасибо, ошибка пошла сейчас, но TotaHours неправильно вычисляется для некоторого сотрудника, например 15:36 до 16:37, общее количество часов наступает 1:37, не могли бы вы рассказать, где я делаю неправильный – User12345

2

Не проще ли просто отбрасывать нулевые значения (возврат датированного в секундах от даты и времени нулевого значения - это то, что, вероятно, переполняет ваш запрос), а также использовать «hh» для datediff? Или вы ищете количество минут (вы НУЖНЫ секунды ?? Если это для расписаний и т.д., секунды на самом деле не важны, не так ли?)

SELECT 
    EMPLOYEEID, 
    CASE 
     WHEN In_Time IS NOT NULL AND Out_Time IS NOT NULL THEN sum(DateDiff(hh, In_Time, Out_Time)) 
     ELSE 0 
    END as TotalHours 
FROM HR_EMPLOYEES 

Edit: хорошо в течение нескольких часов/минуты просто использовать :

SELECT 
    EMPLOYEEID, 
    CASE 
     WHEN In_Time IS NOT NULL AND Out_Time IS NOT NULL THEN sum(DateDiff(mi, In_Time, Out_Time))/60.0 
     ELSE 0 
    END as TotalHours 
FROM HR_EMPLOYEES 

Это даст вам часы плюс часть минут (около 90 минут = 1,5 часа)

Edit2: если вы хотите минут как фактические минут, а не фракция использовать это:

SELECT 
    EMPLOYEEID, 
    CASE 
     WHEN In_Time IS NOT NULL AND Out_Time IS NOT NULL THEN 
      sum(DateDiff(hh, In_Time, Out_Time) + -- Total hours 
      DateDiff(mi, In_Time, Out_Time) % 60 * .01) -- Total minutes (divided by 100 so that you can add it to the hours) 
     ELSE 0 
    END as TotalHours 
FROM HR_EMPLOYEES 
+0

: no , Мне нужны только часы и минуты – User12345

+0

Ok отредактировано - используйте второй запрос, не нужно для всех этих сумм действительно – Charleh

+0

спасибо, но не могли бы вы рассказать мне, как попасть в этот формат (90 минут = 1,30 часа) – User12345

Смежные вопросы