创建一个存储过程以从时间表 table 中找出加班的员工

Create a stored procedure to find out employees who has overtime from timesheet table

我在下面的数据库中有这个。 (我不要求完整的代码想法就足够了)

在时间表 table 中,样本数据是这样的:

条件如下:

条件对我来说似乎很愚蠢,我可以在设计中使用更好的模式并非常有效地解决它。不过在面试的时候被问过一次,我用了SQL server cursor 但是不满足所有条件。任何人都可以帮助了解如何解决这个问题。

这是我的解决方案示例:

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

结束

如果可以,我需要澄清一下。虽然必须尽快赶走,但有人应该结束,否则我明天会去取。

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

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 时间,上述方法适合通宵工作。

如果有人在 运行 报告时正在工作,您是否愿意在接下来的几天摘要中计算该会话,即当他们注销时,或者您是否需要指定一个截止时间?

您可能想减少他们在午夜的时间,以计算他们通宵工作的每个日期的小时数。请稍微说明一下。