挑战:考勤资料处理,高分相送

考勤资料表(kqm_mstr)如下:
kqm_gh kqm_rq kqm_sj
001006 20030713 07:48
001006 20030713 12:13
001006 20030713 13:07
001006 20030713 17:31
001006 20030713 18:22
001006 20030713 23:30

排班: 上午:08:00-12:00 下午:13:30-17:30 加班18:30始
想要如下结果:

kqm_gh kqm_rq m_in m_out a_in a_out n_in n_out ot
0010006 20030713 07:48 12:13 13:07 17:31 18:22 23:30 5

字段说明如下:
(kqm_gh工号 kqm_rq日期 m_in上午上班 m_out上午下往 a_in下午上班 a_out下午下班 n_in晚上上班 n_out晚上下班 ot加班时数(以半小时为单位))

---------------------------------------------------------------

这种数据需要使用中间表,使用程序对每个员工的考勤数据进行处理,处理完后插入到中间表中,因为早上上班他可以打两次卡,下班也可以打两次卡,直接用SELECT语句是不行的
---------------------------------------------------------------

PB中用复合报表实现
---------------------------------------------------------------

up
---------------------------------------------------------------

朋友,我这几天也正在写考勤的处理程序,可以切磋一下,我的邮箱是[email protected].
对在合法的考勤时间范围内,我的处理是按有利员工原则,在迟到范围中有两条记录,则取较大的那条数据,而另外的数据会做为无效刷卡记录,对考勤结果无影响,但写入了日志记录供查询用。在存储过程中,按每天每员工来循环处理,取得当天员工的班次,每个上下班时间,然后查询是否在此班次有在时间范围内的刷卡记录,有取按原则取得一条,如果还有写入日志。
。。。
---------------------------------------------------------------

我也做过考勤管理系统也有上面格式的报表,我是建立了一个原始刷卡记录的表,所有刷卡的记录都有, 也建立了考勤作息时间表. 用存储过程从原始刷卡记录表中逐条取某段时间的某人的数据,然后插入到插入到你上面需要出的那个表中, 做是做出来了, 当执行时有点慢.
---------------------------------------------------------------

UP一下,我現在也在做考勤管理系統,也好複雜,明天跟你切磋一下吧.
---------------------------------------------------------------

你的排班就存在问题,这样不好处理的。
排班规则:
上班最早有效打卡时间 上班最晚有效打卡时间 中午最早有效打卡时间 中午最晚有效打卡时间 下午下班最早有效打卡时间 下午下班最晚有效打卡时间 晚上加班最早有效打卡时间 晚上加班最晚有效打卡时间

然后用打卡数据里的数据去套进排班规则

我一直这样做的,我集团公司的排班规则针对行政,生产,销售达几十种排班规则。

有时也需要根据打卡纪录进行排班
---------------------------------------------------------------

/*
排班: 上午:08:00-12:00 下午:13:30-17:30 加班18:30始

处理原则:
1:上班前30分钟,上班后15分钟有效。 比如8:00上班,则取7:30-8:15之间最大的一笔考勤记录为准。
2:下班后30分钟有效。 比如17:30下班,则取17:30-18:00之间的最大一笔资料。
3:加班不足半小时不算。比如19:00 - 20:22 则只算一个小时。

想要如下结果:
kqm_gh kqm_rq m_in m_out a_in a_out n_in n_out ot
0010006 20030713 07:48 12:13 13:07 17:31 18:22 23:30 5

字段说明如下:
(kqm_gh工号 kqm_rq日期
m_in上午上班 m_out上午下往
a_in下午上班 a_out下午下班
n_in晚上上班 n_out晚上下班
ot加班时数(以半小时为单位))
--排班表说明
description 为说明文字,表明这项代表什么
,在以后的数据处理中意义不太
,如果要让其有作用,后面的数据
处理必须用动态生成SQL的方法
time 为此项目的标准时间,可根据需要设置
min 为提前时间,可根据需要设置
max 为推后时间,可根据需要设置
如果 min 或 max 值为 NULL,视为加班项

*/

--建立考勤表
create table kqm_mstr(kqm_gh varchar(6),kqm_rq int,kqm_sj datetime)
insert into kqm_mstr
select '001006',20030713,'07:48'
union all select '001006',20030713,'08:15'
union all select '001006',20030713,'12:13'
union all select '001006',20030713,'12:14'
union all select '001006',20030713,'13:07'
union all select '001006',20030713,'17:31'
union all select '001006',20030713,'18:32'
union all select '001006',20030713,'23:30'
union all select '001007',20030713,'08:15'
union all select '001007',20030713,'13:07'
union all select '001007',20030713,'17:31'
union all select '001007',20030713,'19:32'
union all select '001007',20030713,'22:30'

--建立排班表
create table tb_pbb(description varchar(10)
,time datetime,min int,max int)

insert into tb_pbb
select '上午-上班','08:00',30,15
union all select '上午-下班','12:00',0,30
union all select '下午-上班','13:30',30,15
union all select '下午-下班','17:30',0,30
union all select '加班','18:30',null,null --如果

--得到结果,如果排班表中的项目不定的话,要用动态表的方法
select a.*,b.[加班-开始],b.[加班-结束],b.加班数
from(
select kqm_gh as 工号,kqm_rq as 日期
,max(case description when '上午-上班' then kqm_sj end) as '上午-上班'
,max(case description when '上午-下班' then kqm_sj end) as '上午-下班'
,max(case description when '下午-上班' then kqm_sj end) as '下午-上班'
,max(case description when '下午-下班' then kqm_sj end) as '下午-下班'
from(
select kqm_gh ,kqm_rq ,convert(varchar(5),max(kqm_sj),108) as kqm_sj
,description
from kqm_mstr a,tb_pbb b
where a.kqm_sj between dateadd(mi,-b.min,b.time) and dateadd(mi,b.max,b.time)
group by kqm_gh ,kqm_rq ,description
) aa group by kqm_gh ,kqm_rq
) a,(
select a.kqm_gh,a.kqm_rq
,convert(varchar(5),max(kqm_sj),108) as [加班-开始]
,convert(varchar(5),min(kqm_sj),108) as [加班-结束]
,datediff(mi,min(kqm_sj),max(kqm_sj))/30 as 加班数
,description
from kqm_mstr a,tb_pbb b
where a.kqm_sj > b.time and b.min is null and b.max is null
group by kqm_gh ,kqm_rq ,description
) b where a.工号=b.kqm_gh and a.日期=b.kqm_rq

drop table kqm_mstr,tb_pbb
---------------------------------------------------------------

按相邻的两个时间配对:

select kqm_gh
,kqm_rq
,(select min(kqm_sj)
from #kqm_mstr
where kqm_gh = T.kqm_gh
and kqm_rq = T.kqm_rq
) as m_in
,(select min(kqm_sj)
from #kqm_mstr
where kqm_gh = T.kqm_gh
and kqm_rq = T.kqm_rq
and kqm_sj >(select min(kqm_sj)
from #kqm_mstr
where kqm_gh = T.kqm_gh
and kqm_rq = T.kqm_rq
)
) as m_out
,(select min(kqm_sj)
from #kqm_mstr
where kqm_gh = T.kqm_gh
and kqm_rq = T.kqm_rq
and kqm_sj > (select min(kqm_sj)
from #kqm_mstr
where kqm_gh = T.kqm_gh
and kqm_rq = T.kqm_rq
and kqm_sj >(select min(kqm_sj)
from #kqm_mstr
where kqm_gh = T.kqm_gh
and kqm_rq = T.kqm_rq
)
)

) as a_in
,(select min(kqm_sj)
from #kqm_mstr
where kqm_gh = T.kqm_gh
and kqm_rq = T.kqm_rq
and kqm_sj >(select min(kqm_sj)
from #kqm_mstr
where kqm_gh = T.kqm_gh
and kqm_rq = T.kqm_rq
and kqm_sj > (select min(kqm_sj)
from #kqm_mstr
where kqm_gh = T.kqm_gh
and kqm_rq = T.kqm_rq
and kqm_sj >(select min(kqm_sj)
from #kqm_mstr
where kqm_gh = T.kqm_gh
and kqm_rq = T.kqm_rq
)
)

)
) as a_out
,(select min(kqm_sj)
from #kqm_mstr
where kqm_gh = T.kqm_gh
and kqm_rq = T.kqm_rq
and kqm_sj >(select min(kqm_sj)
from #kqm_mstr
where kqm_gh = T.kqm_gh
and kqm_rq = T.kqm_rq
and kqm_sj >(select min(kqm_sj)
from #kqm_mstr
where kqm_gh = T.kqm_gh
and kqm_rq = T.kqm_rq
and kqm_sj > (select min(kqm_sj)

Published At
Categories with 数据库类
Tagged with
comments powered by Disqus