2013-06-01 46 views
0

我有這種類型的表計算過量/短

CREATE TABLE attendance 
(
    Date datetime, 
    Timein datetime, 
    Timeout datetime, 
    Spend nvarchar(50), 
    excessshort nvarchar(50) 
) 

我的數據是這樣的。

Date      TimeIn     Timeout     Spend  excessshort 
2013-01-01 00:00:00.000 2013-01-01 09:14:00.000 2013-01-01 19:06:00.000 09:52:00 

我想計算excesshort

過量短來自所花費的時間是指一個僱員花費9小時52分鐘那麼其過量零時52分鐘,如果僱員花費8小時44分鐘然後其短00: 16分鐘我們有9到6小時的時間轉換。

回答

0

這是一個快速和骯髒的解決方案。總之,花費列沒有任何幫助,因爲它是一個varchar,我們需要做日期數學。

爲了演示的目的,我做了一個表格變量,我需要三列。使用datediff函數,我們將計算每個人計時的分鐘數,然後減去9小時(540分鐘)內的分鐘數。

如果答案是肯定的,那麼這個人在超過9小時的時間內計時。如果是負面的,他們就會失敗。如果剛剛540分鐘,那麼他們準時。

就像我說的那樣,它很快而且很髒。你必須將這些概念適應你的具體情況。我不知道你是否正在嘗試更新表格或只是運行報告或其他內容。

declare @attendance TABLE 
(
    id int IDENTITY(1,1), 
    Date datetime, 
    Timein datetime, 
    Timeout datetime 
) 
insert into @attendance (date,timein,timeout) values ('2013-01-01 00:00:00.000','2013-01-01 09:14:00.000','2013-01-01 19:06:00.000') 
insert into @attendance (date,timein,timeout) values ('2013-01-01 00:00:00.000','2013-01-01 09:14:00.000','2013-01-01 17:45:00.000') 
insert into @attendance (date,timein,timeout) values ('2013-01-01 00:00:00.000','2013-01-01 09:00:00.000','2013-01-01 18:00:00.000') 


declare @shiftHours int, @shiftMinutes int 
set @shiftHours = 9 
set @shiftMinutes = @shiftHours * 60 


select 
    datediff(minute,timein,timeout) as minutesClockedIn, 
    datediff(minute,timein,timeout) - @shiftMinutes as offset, 
    excessOrShort = 
     case 
      when (datediff(minute,timein,timeout) - @shiftMinutes) > 0 then 'excess' 
      when (datediff(minute,timein,timeout) - @shiftMinutes) < 0 then 'short' 
      else 'ontime' 
     end, 
    excessOrShortDescription = 
     case 
      when (datediff(minute,timein,timeout) - @shiftMinutes) > 0 
      then right('0' + cast(abs((datediff(minute,timein,timeout) - @shiftMinutes)/60) as varchar(2)),2) + ':' + right('0' + cast(abs((datediff(minute,timein,timeout) - @shiftMinutes) % 60) as varchar(2)),2) + ' in excess' 
      when (datediff(minute,timein,timeout) - @shiftMinutes) < 0 
      then right('0' + cast(abs((datediff(minute,timein,timeout) - @shiftMinutes)/60) as varchar(2)),2) + ':' + right('0' + cast(abs((datediff(minute,timein,timeout) - @shiftMinutes) % 60) as varchar(2)),2) + ' short' 
      else 'ontime' 
     end 

from @attendance 

下面的這個CTE版本更具可讀性,但是做同樣的事情。我只使用CTE來消除一些重複的日期和時間

declare @attendance TABLE 
(
    id int IDENTITY(1,1), 
    Date datetime, 
    Timein datetime, 
    Timeout datetime 
) 
insert into @attendance (date,timein,timeout) values ('2013-01-01 00:00:00.000','2013-01-01 09:14:00.000','2013-01-01 19:06:00.000') 
insert into @attendance (date,timein,timeout) values ('2013-01-01 00:00:00.000','2013-01-01 09:14:00.000','2013-01-01 17:45:00.000') 
insert into @attendance (date,timein,timeout) values ('2013-01-01 00:00:00.000','2013-01-01 09:00:00.000','2013-01-01 18:00:00.000') 


declare @shiftHours int, @shiftMinutes int 
set @shiftHours = 9 
set @shiftMinutes = @shiftHours * 60 
-- populate CTE for use by select statement below 
;with shiftData as (
    select 
     date, 
     datediff(minute,timein,timeout) as minutesClockedIn, 
     datediff(minute,timein,timeout) - @shiftMinutes as totalMinutesOffset, 
     excessOrShort = 
      case 
       when (datediff(minute,timein,timeout) - @shiftMinutes) > 0 then 'excess' 
       when (datediff(minute,timein,timeout) - @shiftMinutes) < 0 then 'short' 
       else 'ontime' 
      end 
    from @attendance 
) 
-- use the CTE 
select Date, 
    minutesClockedIn, 
    totalMinutesOffset, 
    totalMinutesOffset/60 as hoursOffset, 
    totalMinutesOffset % 60 as minutesOffset, 
    excessOrShort, 
    excessOrShortDescription = 
     case 
      when excessOrShort in ('excess','short') 
      then right('0' + cast(abs(totalMinutesOffset/60) as varchar(2)),2) + ':' + right('0' + cast(abs(totalMinutesOffset % 60) as varchar(2)),2) + ' ' + excessOrShort 
      else 'ontime' 
     end 
from shiftData