我有这种类型的表
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
我想计算多余的短缺
多余的短缺来自花费的时间意味着员工花了9小时52分钟然后超过00:52分钟,如果员工花了8小时44分钟然后短00:16分钟我们有9到6小时的时间班次。
答案 0 :(得分: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