读书人

复杂的插入操作的存储过程解决办法

发布时间: 2012-04-06 12:22:24 作者: rapoo

复杂的插入操作的存储过程
各位朋友,分别有表1和表2,表1的结构如下
员工编号  刷卡时间
CA001 2007-7-1 07:30
HA001  2007-7-1 08:30
ZA001  2007-7-1 09:30
CA001  2007-7-1 18:30
ZA001  2007-7-1 20:30
HA001  2007-7-2 07:30
KA001  2007-7-2 18:30
。。。。。  。。。。。。。。。。。。。。

表2的结构如下:
员工编号  上班  下班  刷卡时间


想做这样一个存储过程,假如用户输入起始时间和结束时间,然后就可以将表1里面对应时间段的记录插入到表2,例如起始时间为2007-7-1,结束时间为:2007-7-2,根据表1的刷卡记录要求生成表2以下的记录:
 
员工编号  上班  下班  日期
CA001 07:30 18:30 2007-7-1
HA001 08:30 空值 2007-7-1
ZA001 09:30 20:30 2007-7-1
HA001 07:30 空值 2007-7-2
KA001 空值 18:30 2007-7-2

提示:如果该员工当天只刷了一次卡,0:00至12:00时间就插入到上班1,12:00至23:59的时间就插入到下班,请问这样的存储过程可以有机会实现吗?如果可以,诚心请各位朋友赐教,谢谢!!!


[解决办法]
create table tab(员工编号 varchar(10),刷卡时间 datetime)
insert tab
select 'CA001 ', '2007-7-1 07:30 '
union select 'HA001 ', '2007-7-1 08:30 '
union select 'ZA001 ', '2007-7-1 09:30 '
union select 'CA001 ', '2007-7-1 18:30 '
union select 'ZA001 ', '2007-7-1 20:30 '
union select 'HA001 ', '2007-7-2 07:30 '
union select 'KA001 ', '2007-7-2 18:30 '

CREATE TABLE TAB2(员工编号 VARCHAR(10),上班 datetime,下班 datetime,刷卡时间 datetime)

go


create proc p_insert_time
@start_time datetime,
@end_time datetime
as

insert TAB2(员工编号,上班,下班,刷卡时间)
select 员工编号,
up =case when right(convert(char(16),min(刷卡时间),120),5) between '00:00 ' and '12:00 ' then right(convert(char(16),min(刷卡时间),120),5) else null end ,
down=case when right(convert(char(16),max(刷卡时间),120),5) between '12:00 ' and '23:59 ' then right(convert(char(16),max(刷卡时间),120),5) else null end ,
convert(char(10),刷卡时间,120)
from tab
where convert(char(10),刷卡时间,120)> =@start_time and convert(char(10),刷卡时间,120) <=@end_time
group by 员工编号,convert(char(10),刷卡时间,120)

go

exec p_insert_time '2007-7-1 ', '2007-7-2 '
go
select * from tab2

go
drop proc p_insert_time
drop table tab,tab2


/* 结果

员工编号 上班 下班 刷卡时间
---------- ------------------------------------------------------ ------------------------------------------------------ ------------------------------------------------------
CA001 1900-01-01 07:30:00.000 1900-01-01 18:30:00.000 2007-07-01 00:00:00.000
HA001 1900-01-01 08:30:00.000 NULL 2007-07-01 00:00:00.000
ZA001 1900-01-01 09:30:00.000 1900-01-01 20:30:00.000 2007-07-01 00:00:00.000
HA001 1900-01-01 07:30:00.000 NULL 2007-07-02 00:00:00.000


KA001 NULL 1900-01-01 18:30:00.000 2007-07-02 00:00:00.000

(5 row(s) affected)
*/
[解决办法]
declare @Test table (员工编号 varchar(10), 刷卡时间 datetime)
insert @Test
select 'CA001 ', '2007-7-1 07:30 ' union all
select 'HA001 ', '2007-7-1 08:30 ' union all
select 'ZA001 ', '2007-7-1 09:30 ' union all
select 'CA001 ', '2007-7-1 18:30 ' union all
select 'ZA001 ', '2007-7-1 20:30 ' union all
select 'HA001 ', '2007-7-2 07:30 ' union all
select 'KA001 ', '2007-7-2 18:30 '

declare @First datetime, @Last datetime
select @First = '2007-07-01 ', @Last = '2007-07-02 '
set @Last = dateadd(day, 1, @Last)

select
员工编号,
上班 = case when datepart(hour, min(刷卡时间)) <12 then min(刷卡时间) else null end,
下班 = case when datepart(hour, max(刷卡时间)) > =12 then min(刷卡时间) else null end,
日期 = convert(varchar(10), 刷卡时间, 120) from @Test
where 刷卡时间 > =@First and 刷卡时间 < @Last
group by 员工编号, convert(varchar(10), 刷卡时间, 120)
order by convert(varchar(10), 刷卡时间, 120), 员工编号

/*
CA0012007-07-01 07:30:00.0002007-07-01 07:30:00.0002007-07-01
HA0012007-07-01 08:30:00.000NULL2007-07-01
ZA0012007-07-01 09:30:00.0002007-07-01 09:30:00.0002007-07-01
HA0012007-07-02 07:30:00.000NULL2007-07-02
KA001NULL2007-07-02 18:30:00.0002007-07-02
*/

读书人网 >SQL Server

热点推荐