首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >SQL -对员工开始时间进行分类。

SQL -对员工开始时间进行分类。
EN

Stack Overflow用户
提问于 2014-04-27 16:59:05
回答 3查看 781关注 0票数 4

我有一个SQL表,其中存储每个员工的进出时间戳。

有些员工不止一次地打卡(是因为他们没有听到卡片被读到),还有一些员工是因为某种原因而打卡的(也许他们会遇到朋友并保持交谈1到2分钟),他们需要等几分钟才能再次打卡才能进入转门。

示例SQL表数据如下(仅3名雇员):

现在,我想分类每一次,以了解什么是正确的时间戳,等等。

例如:

在您看到的EMP_01 (黄色记录)中,LAST_LEAVE在技术上是00:38:21,但是很明显,员工敲了两下,这就是真正的LAST_LEAVE是00:38:16的原因。

但是,EMP_04还有其他一些问题,如果你看到最后4张唱片,他连续3张,但这并不是因为他没有听到传感器发出的哔声,而是因为他从另一扇门离开时,谁知道是什么时候,但我们知道他在1小时后再次进入,等等。

那么,对如何处理这件事有什么建议吗?以及如何分配我的“状态”标志?

更新

例如,如果EMP_04有3个连续的相同类型的时间戳(IN's或OUT's):

  • 上午9:04:27 (IN)
  • 上午9:04:35 (IN)
  • 上午9:04:40 (IN)

我的容忍时间是120秒,所以第一次9:04:27是可以的,但是接下来的两个连续的时间戳应该是无效的,因为我的容忍度是120秒。

但是,例如,如果EMP_04具有以下连续时间戳:

  • 上午9:04:27 (IN)
  • 上午9:04:35 (IN)
  • 上午9:08:10 (IN)

那么唯一被标记为不活动的时间是上午9:04:35。因为上午9:04.35到9:08:10之间大于2分钟。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-04-30 15:34:21

首先,承认@RamRS将艰苦的工作放入触发器中,这里有一个经过测试,应该可以启动。显然,需要对拐角处的情况进行一些健壮的测试:

代码语言:javascript
运行
复制
CREATE TRIGGER TS_FindDups ON dbo.TS FOR INSERT
AS
BEGIN

;WITH DupRecords
AS
(
        SELECT i.EmployeeId, i.[TimeStamp]
          FROM inserted i
    INNER JOIN dbo.TS SRC ON i.EmployeeId = SRC.EmployeeId AND i.EntranceType = SRC.EntranceType
         WHERE SRC.[Status] != 'Inactive'
               /* same day (nice...thanks to RamRS) */
               AND CAST(i.[TimeStamp] AS date) =  CAST(SRC.[TimeStamp] AS date)
               /* only checking newer timestamps (also need this so DATEDIFF <= 2 works correctly) */
               AND i.[TimeStamp] > SRC.[TimeStamp]
               /* newer timestamps are less than two minutes for same Employee, same day, same EntranceType */
               AND DATEDIFF(MINUTE, SRC.[TimeStamp], i.[TimeStamp]) <= 2
)

      UPDATE dbo.TS
         SET [Status] = 'Inactive'
        FROM dbo.TS SRC
  INNER JOIN DupRecords ON SRC.EmployeeId = DupRecords.EmployeeId AND SRC.[TimeStamp] = DupRecords.[TimeStamp]

END
票数 2
EN

Stack Overflow用户

发布于 2014-04-30 13:55:41

正如@mdisibio所述,我们可以使用触发器在插入行时添加“非活动”值来复制行。

这个触发器的大致草图如下:

代码语言:javascript
运行
复制
CREATE TRIGGER trg_FindDups ON tbl_TimeStamp FOR INSERT
AS
BEGIN
    DECLARE @CurrentMaxSwipeTime DATETIME
    DECLARE @SwipeType
    SELECT @SwipeType = EntranceType FROM INSERTED

    IF (@SwipeType = 'O')
    BEGIN
        /* Employee is swiping OUT */
        SELECT @CurrentMaxSwipeTime = MAX(T.TimeStamp) FROM tbl_TimeStamp T 
        WHERE T.EmployeeID = (SELECT EmployeeID FROM INSERTED) /* Same employee */
        AND DATE(T.TimeStamp) = CAST(GETDATE() AS DATE) /* Same date */
        AND DATEDIFF(minute,T.TimeStamp,GETDATE())<2 /* Within 2 minutes */
        AND T.Status <> 'INACTIVE' /* of an active swipe */
        AND T.EntraceType = 'O' /* Swiping out */
        AND T.TimeStamp <> (SELECT TimeStamp FROM INSERTED) /* not the row we just inserted, H/T @mdisibio
        IF @CurrentMaxSwipeTime IS NOT NULL
            /* SET Status to INACTIVE */
            UPDATE tbl_TimeStamp SET Status='INACTIVE' WHERE EmployeeID=(SELECT EmployeeID FROM INSERTED) AND TimeStamp=(SELECT TimeStamp FROM INSERTED)
    END

    ELSE
    BEGIN
        /* Employee is swiping in */
        SELECT @CurrentMaxSwipeTime = MIN(T.TimeStamp) FROM tbl_TimeStamp T 
        WHERE T.EmployeeID = (SELECT EmployeeID FROM INSERTED) /* Same employee */
        AND DATE(T.TimeStamp) = CAST(GETDATE() AS DATE) /* Same date */
        AND DATEDIFF(minute,T.TimeStamp,GETDATE())<2 /* Within 2 minutes */
        AND T.Status <> 'INACTIVE' /* of an active swipe */
        AND T.EntraceType = 'I' /* Swiping in */
        AND T.TimeStamp <> (SELECT TimeStamp FROM INSERTED) /* not the row we just inserted, H/T @mdisibio
        IF @CurrentMaxSwipeTime IS NOT NULL
            /* SET Status to INACTIVE */
            UPDATE tbl_TimeStamp SET Status='INACTIVE' WHERE EmployeeID=(SELECT EmployeeID FROM INSERTED) AND TimeStamp=(SELECT TimeStamp FROM INSERTED)
    END
END

我在Server上工作已经有几年了,但我真的希望代码中没有错误。

--

干杯,

随机存取存储器

票数 1
EN

Stack Overflow用户

发布于 2014-04-30 15:46:56

让我快速总结一下你们的问题,然后一个接一个地提出:

  1. 误刷两次时复制记录。应如何设置状态?
  2. 复制的记录,因为不是所有的门有滑动和不记录相应的输出记录。同样,应该如何设置状态?

假设:

  1. 如果人们错误地多次扫描,你可以得到重复的输入和输出记录。
  2. 你不能在目前没有卡片扫描仪的门上.
  3. 这是一个不完善的系统,因此您不会删除\忽略不同场景中的任何扫描。

所以..。在中间几分钟内复制记录。为了确定用户的状态,您必须查看他们的历史记录。我相信你的想法,有一个容忍几分钟是一个很好的想法,虽然这应该检查在输入和输出扫描。因为在你的内心里,你应该总是第一个。因为你应该一直吃最后一杯。

我想的是,每次插入/更新/删除特定员工的时间戳记录时,都会重新计算当天的所有状态。这样,如果有重复的扫描,您就不必担心在不同的行上来回调整状态。

您必须重新计算状态,如下所示:

  1. FIRST_ENTRANCE -在特定的一天,员工在EntranceType i上的第一个时间戳行
  2. LAST_LEAVE -在特定的一天,所有员工在with EntranceType O上的员工的最后一个时间戳行。在设置此日期之前,请检查此日的所有其他员工,不要在同一天使用此选项。
  3. FIRST_IN -在特定的一天为所有员工在with EntranceType i上为员工盖上第一个时间戳行。在设置此日期之前,请检查此日的所有其他员工,不要在同一天使用此选项。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23326277

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档