创建存储过程以查找从时间表表中加班的员工

时间:2015-04-21 13:59:58

标签: sql sql-server sql-server-2008 stored-procedures time

我的数据库下面有这个。 (我不是要求完整的代码构思就够了) Schema Design

在时间表中,示例数据是这样的: Sample data

现在有条件:

  • 必须编写存储过程
  • 状态“IN”表示他/她进入办公室时“OUT” 表示他/她何时离开办公室或离开办公室 办公室。
  • 每次进入或离开时,都会使用 卡,它将进入数据库。所以在同一天,那里 可能是一个人的多个细节。
  • 我们需要在下午5点之后向员工展示超时。
  • 请注意,一个人今天可以登录,明天或之后可以出去 在他们之间,他/她也可以进出哪些不会伤害到 超时。

条件对我来说似乎很愚蠢,我可以在设计中使用更好的架构并且非常有效地解决它。然而,它在面试考试中被问过一次,我使用SQL服务器游标,但它不符合所有条件。任何人都可以帮助了解如何解决这个问题。

这是我的解决方案示例:

Create PROCEDURE [dbo].[sp_get_over_times] 
@officeHours                    INT = 8
AS
BEGIN

SET NOCOUNT ON;
DECLARE @emp_id         VARCHAR(10);
DECLARE @att_date       Date = NULL;
DECLARE @att_time       SMALLDATETIME = NULL;
DECLARE @status         VARCHAR(4) = NULL;
DECLARE @emp_id_2           VARCHAR(10) = NULL;
DECLARE @att_date_2     DATE = NULL;
DECLARE @status_2           VARCHAR(4) = NULL;
DECLARE @att_time_2     SMALLDATETIME = NULL;

DECLARE @duration       int = NULL;

DECLARE c1 CURSOR READ_ONLY 
        FOR 
        SELECT Emp_id,  Att_Date,Att_time
        FROM dbo.timesheet 
        WHERE STATUS = 'IN'
        GROUP BY Emp_id, Att_Date,Att_time
        OPEN c1
        FETCH NEXT FROM c1 INTO @emp_id,@att_date,@att_time


        WHILE @@FETCH_STATUS = 0
        BEGIN

                SELECT TOP 1 @emp_id_2 = Emp_id, @att_date_2 = Att_Date,  @att_time_2 = Att_time
                FROM dbo.timesheet 
                WHERE STATUS = 'OUT' AND Emp_id = @emp_id AND Att_Date = @att_date;

                IF(@emp_id_2 IS NOT NULL) BEGIN
                    SET @duration = DATEDIFF(minute,@att_time,@att_time_2);
                    IF(@duration < 0 ) BEGIN
                        SET @duration = @duration * -1;
                    END
                    IF(@duration > @officeHours) BEGIN
                       SELECT @emp_id, (@duration- @officeHours) AS 'OverTime';              
                    END                  
                END    
                SET @emp_id_2 = NULL;
                FETCH NEXT FROM c1 INTO   @emp_id,@att_date,@att_time
        END

        CLOSE c1
        DEALLOCATE c1

END

1 个答案:

答案 0 :(得分:2)

如果没问题,我需要澄清一下。不过要尽快赶去,但是有人应该结束,否则我明天会去接。

最初,如果您从这样的查询开始......

declare @reportend datetime
set @reportend = '20150422'

SELECT outs.emp_id, 
       outs.att_date, 
       max(ins.att_time) 'In', 
       outs.att_time 'Out', 
       datediff(minute, max(ins.att_time), outs.att_time) 'Mins'
FROM timesheet outs
INNER JOIN timesheet ins
   on outs.emp_id = ins.emp_id
   and ins.att_time < outs.att_time
   and ins.status = 'IN'
WHERE outs.status = 'OUT'
   and outs.att_time between dateadd(day,-1,@reportend) and @reportend
group by outs.emp_id, outs.att_date, outs.att_time

您可以开始配对IN和OUT事件 - 您甚至可以在FROM子句中用括号括起上面的内容,并按员工的方式将这些内容包括在内。

然而,当一段时间过去并且您没有看到匹配的IN和OUT事件对时会发生什么?这是您在数据中单独/正确报告的内容,因此我们可以假设所有对都已完成吗?

上述方法可以满足夜间工作,假设您正在查看过去24小时的OUT时间。

如果某人当前在运行报告时正在工作,您是否乐意在接下来的几天内汇总该会话,即他们何时退出,或者您是否需要指定截止期?

您可能希望在午夜减少他们的时间,计算他们在一夜之间工作的每个日期的小时数。请澄清一下。