计算超额/短期

时间:2013-06-01 07:06:19

标签: sql-server-2005

我有这种类型的表

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小时的时间班次。

1 个答案:

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