Sql 创建存储过程以从时间表表中查找加班的员工
我有下面的数据库。(我不是要完整的代码,只要有一个想法就足够了) 在时间表表中,示例数据如下所示: 以下是条件:Sql 创建存储过程以从时间表表中查找加班的员工,sql,sql-server,sql-server-2008,stored-procedures,time,Sql,Sql Server,Sql Server 2008,Stored Procedures,Time,我有下面的数据库。(我不是要完整的代码,只要有一个想法就足够了) 在时间表表中,示例数据如下所示: 以下是条件: 必须编写存储过程 状态“IN”表示他/她进入办公室和离开办公室的时间 表示他/她离开办公室或离开办公室的时间 办公室 每次有人使用 它将进入数据库。所以在同一天,有 一个人可以有多个输入和输出 我们需要在下午5点后向员工展示随时间变化的信息 请注意,一个人今天可以登录,明天或之后可以外出。 在这两者之间,他/她也可以进出,这不会伤害到客户 加班 条件对我来说似乎很愚蠢,我可以
- 必须编写存储过程
- 状态“IN”表示他/她进入办公室和离开办公室的时间 表示他/她离开办公室或离开办公室的时间 办公室李>
- 每次有人使用 它将进入数据库。所以在同一天,有 一个人可以有多个输入和输出
- 我们需要在下午5点后向员工展示随时间变化的信息李>
- 请注意,一个人今天可以登录,明天或之后可以外出。
在这两者之间,他/她也可以进出,这不会伤害到客户
加班
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
的列,当有更新inout\u time
时,只需计算in\u time
和out\u time
之间的差异,并在表中更新total\u time
!!在你的情况下,什么是加班?我不太明白你最后的要求。谢谢你的回答。非常感谢。他们没有提到数据匹配,所以我们可以离开这一部分。