午夜时间计算

时间:2012-12-31 17:25:58

标签: sql sql-server-2008 time-and-attendance

我有一个按以下顺序存储时钟条目的表。

UID         Clock                    Status
===         =====                    ======

R01         2013-01-01 17:00:00      Clockin
R01         2013-01-01 17:10:00      Clockin
R01         2013-01-01 23:45:00      Clockin

我目前的解决方案是使用最小/最大日期与案例和左连接按以下顺序排列条目

UID        Date         ClockIn    ClockOut
===        ====         =======    ========
R01        2013-01-01    17:00:00  23:45:00

当时钟输入超过午夜时,我应该如何处理这种情况。即,

UID         Clock                    Status
===         =====                    ======
R01         2013-01-01 17:00:00      Clockin
R01         2013-01-02 00:45:00      Clockin

由于以上将产生如下所示的2个条目,这将导致员工零时间7.45小时。

UID        Date          ClockIn               ClockOut
===        ====          =======               ========
R01        2013-01-01    2013-01-01 17:00:00   2013-01-01 17:00:00
R01        2013-01-02    2013-01-02 00:45:00   2013-01-02 00:45:00

提前致谢。

以下是SQL 2008R2中存储过程使用的代码

SELECT A.Device,A.DID, A.Name, A.ClockDate,Clockin ,ClockOut
FROM 
(
    SELECT Device,DID,Name, CONVERT(DATE, DeviceClock) 'ClockDate', 
    min(case when clock=Clock and Status ='Clock In' OR status='Clock Out' OR status='Access In' then clock  end) 'CLock In'

    FROM TABLE  
    group by Device,DID,Name, CONVERT(DATE, DeviceClock)
) as A
LEFT JOIN 
(
    SELECT Device,DID,Name, CONVERT(DATE, DeviceClock) 'ClockDate', 

max(case when clock=Clock and Status ='Clock in' or status='Clock Out' OR status='Access In' then Clock end) 'Clock Out'


    FROM TABLE 
    group by Device,DID,Name, CONVERT(DATE, DeviceClock)
) as B
ON A.DID = B.DID AND A.ClockDate = B.ClockDate

2 个答案:

答案 0 :(得分:2)

有很多你不在这里考虑。时间/出勤系统非常复杂。例如:

  • 如果您的ClockIn仅在午夜前几分钟而且ClockOut在早上很晚才会怎么样?你哪一天记录时间?
  • 如果时间分配均匀,比如说晚上10点到凌晨2点,那么第1天就是4小时的转换怎么办?还是第2天?或者是两个2小时的轮班?
  • 您是否以UTC格式录制时间?进行本地转换?处理夏令时? (在当地时间减去不是对经过时间的准确测量!)
  • 舍入?多少钱?在什么情况下?
  • 如何处理丢失的拳?重复一拳?

整个系统已经发展到可以处理这些场景。他们通常还会处理加班计算,工作成本计划,日程安排等工作规则 - 但它们都是从您描述的基本问题案例开始的。

您并不总是与下一个打卡,或特定类型的下一个,或同一日期的下一个配对。有许多方案组合需要处理,而不能在简单的sql语句或存储过程中表达这一点。您可以尝试 - 但是您需要处理很多边缘情况。

我会考虑购买已经为您处理过这些案例的产品。如果您打算自己编写 - 请不要在SQL中执行此操作。从SQL获取原始数据并将其与业务逻辑一起使用以生成处理引擎。

答案 1 :(得分:1)

Matt所说的是一个很好的一般性答案,并阅读了他提到的所有警告,但如果你的情况非常简单,那就是所有员工在早上6点之后开始,在午夜之前离开并在我们说完之前完成,凌晨3点,你可以捏造它非常喜欢这样:

SELECT Device,DID,Name, convert( DATE, dateadd(hour, -3, CONVERT(DATE, DeviceClock))) 'ClockDate', 

max(case when clock=Clock and Status ='Clock in' or status='Clock Out' OR status='Access In' then Clock end) 'Clock Out'

FROM TABLE 
group by Device,DID,Name, convert( DATE, dateadd(hour, -3, CONVERT(DATE, DeviceClock)))

在两个联合选择中的每一个。你有效地改变了当天开始和结束3个小时的想法。当然,如果有人在凌晨3点以后工作,或者在凌晨3点之前开始工作,那么这将不起作用。