这是一个快速而肮脏的解决方案。简而言之,该支出列没有任何帮助,因为它是一个 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