Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 创建存储过程以从时间表表中查找加班的员工_Sql_Sql Server_Sql Server 2008_Stored Procedures_Time - Fatal编程技术网

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

Sql 创建存储过程以从时间表表中查找加班的员工,sql,sql-server,sql-server-2008,stored-procedures,time,Sql,Sql Server,Sql Server 2008,Stored Procedures,Time,我有下面的数据库。(我不是要完整的代码,只要有一个想法就足够了) 在时间表表中,示例数据如下所示: 以下是条件: 必须编写存储过程 状态“IN”表示他/她进入办公室和离开办公室的时间 表示他/她离开办公室或离开办公室的时间 办公室 每次有人使用 它将进入数据库。所以在同一天,有 一个人可以有多个输入和输出 我们需要在下午5点后向员工展示随时间变化的信息 请注意,一个人今天可以登录,明天或之后可以外出。 在这两者之间,他/她也可以进出,这不会伤害到客户 加班 条件对我来说似乎很愚蠢,我可以

我有下面的数据库。(我不是要完整的代码,只要有一个想法就足够了)

在时间表表中,示例数据如下所示:

以下是条件:

  • 必须编写存储过程
  • 状态“IN”表示他/她进入办公室和离开办公室的时间 表示他/她离开办公室或离开办公室的时间 办公室
  • 每次有人使用 它将进入数据库。所以在同一天,有 一个人可以有多个输入和输出
  • 我们需要在下午5点后向员工展示随时间变化的信息
  • 请注意,一个人今天可以登录,明天或之后可以外出。
    在这两者之间,他/她也可以进出,这不会伤害到客户
    加班
条件对我来说似乎很愚蠢,我可以在设计中使用更好的模式,并非常有效地解决它。但在面试考试中有一次被问到,我使用了SQL server游标,但它并不满足所有条件。请任何人帮助理解如何解决这个问题

这是我的解决方案示例:

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
Create PROCEDURE[dbo]。[sp\u get\u over\u times]
@办公时间INT=8
作为
开始
不计数;
声明@emp_id VARCHAR(10);
声明@att_date=NULL;
声明@att_time SMALLDATETIME=NULL;
声明@status VARCHAR(4)=NULL;
声明@emp_id_2 VARCHAR(10)=NULL;
声明@att_date_2 date=NULL;
声明@status_2 VARCHAR(4)=NULL;
声明@att_time_2 SMALLDATETIME=NULL;
声明@duration int=NULL;
声明c1游标为只读
对于
选择Emp_id、Att_日期、Att_时间
从dbo.timesheet
其中STATUS='IN'
按Emp_id、Att_日期、Att_时间分组
开放式c1
将下一个从c1获取到@emp_id、@att_date、@att_time
而@@FETCH\u STATUS=0
开始
选择顶部1@emp\u id\u 2=emp\u id、@att\u date\u 2=att\u date、@att\u time\u 2=att\u time
从dbo.timesheet
其中STATUS='OUT'和Emp_id=@Emp_id和Att_Date=@Att_Date;
如果(@emp_id_2不为空)开始
设置@duration=DATEDIFF(分钟、@att_时间、@att_时间2);
如果(@duration<0)开始
设置@duration=@duration*-1;
结束
如果(@duration>@officeHours)开始
选择@emp_id,(@duration-@officeHours)作为“加班”;
结束
结束
设置@emp_id_2=NULL;
将下一个从c1获取到@emp_id、@att_date、@att_time
结束
关闭c1
解除分配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
declare@reportend-datetime
set@reportend='20150422'
选择outs.emp\u id,
out.att_日期,
最大值(ins.att_时间)'In',
outs.att_time“Out”,
datediff(分钟,最大值(内部时间和外部时间)‘分钟’
从时间表中删除
内部联接时间表插件
on out.emp\u id=ins.emp\u id
和ins.att_时间
您可以开始配对输入和输出事件-您甚至可以在FROM子句中用括号括住上述事件,并按员工对分钟进行求和

然而,当一段时间过去了,您没有看到匹配的输入和输出事件对时,会发生什么?这是否是您将在数据中单独/正确地报告的内容,以便我们可以假设所有对都是完整的

上述方法可以满足通宵工作的需要,假设您查看之前24小时的工作时间

如果有人在运行报告时正在工作,您是否愿意在他们注销后的几天内统计该会话,或者您是否需要指定截止时间


你可能想把他们的工作时间缩短到午夜,为他们每晚工作的日子计算小时数。请澄清一下。

您要求的是完整的代码!!好吧,那是违反SO的政策的!!!不知道会不够好既然你已经添加了代码来显示你的努力,我删除了我的否决票!!告诉你,这不是讨厌!!努力总是值得赞赏的!!还有一个主意!我可以说,只需再添加一个名为
total\u time
的列,当有更新in
out\u time
时,只需计算
in\u time
out\u time
之间的差异,并在表中更新
total\u time
!!在你的情况下,什么是加班?我不太明白你最后的要求。谢谢你的回答。非常感谢。他们没有提到数据匹配,所以我们可以离开这一部分。