2012-08-08 46 views
1

我有一张表,它根据用户名通过Time Machine存储员工的登记时间。如果员工多次出拳,那么他的签入将有多个记录。所有那些在首次记录1分钟内出现的记录都是无效的,必须删除。如果第一条记录超过一分钟后的记录有效并且不能删除。那么这第二个有效记录也可能包含随后的记录,因为它们在第二个有效记录的1分钟内是无效的。这些记录也应该被删除,等等。我如何在当前日期的员工的所有登记记录上执行此操作?标志字段不在数据库中,它只是一个证明哪个记录是有效的,哪个是无效的。基于超时删除SQL中的无效记录

The Data in the db is as follows. 

Username    Checktime      CheckType   Flag 
HRA001   7/29/2012 8:16:44 AM    Check-In   Valid 
HRA001   7/29/2012 8:16:46 AM    Check-In   Invalid 
HRA001   7/29/2012 8:16:50 AM    Check-In   Invalid 
HRA001   7/29/2012 8:17:30 AM    Check-In   Invalid 
HRA001   7/29/2012 8:17:50 AM    Check-In   Valid 
HRA001   7/29/2012 8:17:53 AM    Check-In   Invalid 
HRA001   7/29/2012 8:18:40 AM    Check-In   Invalid 
HRA001   7/29/2012 8:18:54 AM    Check-In   Valid 
HRA001   7/29/2012 8:18:56 AM    Check-In   Invalid 
HRA001   7/29/2012 8:18:58 AM    Check-In   Invalid 
HRA001   7/29/2012 8:19:55 AM    Check-In   Valid 
HRA001   7/29/2012 8:20:58 AM    Check-In   Valid 
+0

它更可能是你的时间机器正在被某种恶意软件的攻击。 – 2012-08-08 13:35:30

+0

因为喜欢和机器一起玩并且在几秒钟的空间内多次冲击的人而不是:) – 2012-08-09 03:46:44

回答

1

试试这个:

;WITH users_CTE as 
(
select *,row_number() over (partition by Username order by Checktime) as row from users 
) 
,CTE as(
select row,Username,Checktime,CheckType,0 as totalSeconds,'N' as Delflag from users_CTE where row=1 
union all 
select t.row,t.Username,t.Checktime,t.CheckType,CASE WHEN (c.totalSeconds + DATEDIFF(SECOND,c.Checktime,t.Checktime)) >= 60 then 0 else (c.totalSeconds + DATEDIFF(SECOND,c.Checktime,t.Checktime)) end as totalSeconds, 
CASE WHEN (c.totalSeconds + DATEDIFF(SECOND,c.Checktime,t.Checktime)) >= 60 then 'N' else 'Y' end as Delflag 
--CASE WHEN c.totalSeconds <= 60 then 'Y' else 'N' end as Delflag 
from users_CTE t inner join CTE c 
on t.row=c.row+1 
) 

select Username,Checktime,CheckType,Delflag from CTE 
+0

嘿,这位男士感谢您帮助我从字面上理解。这意味着很多 – 2012-08-08 06:12:12

+1

Np :-)你欢迎... !!! – AnandPhadke 2012-08-08 06:17:28

+0

Hey Anand另外还有一件事,这个查询导致临时表中的数据。现在,如果我想删除我的原始表中的这些无效记录,因为Delflag不是原始表的列。我可以在我的原始表格中添加Delflag列,但是如何做到这一点? – 2012-08-08 07:28:47

0
;WITH users_CTE as 
(
select *,row_number() over (partition by USER_NAME order by CHECKTIME) as row from daily_machine_data 
WHERE Convert(varchar(10),CHECKTIME,101) = Convert(varchar(10),GetDate(),101) AND USER_NAME='HRA002' 
) 
,CTE as(
select row,USERID,USER_NAME,CHECKTIME,CHECKTYPE,VERIFYCODE,CHK_DATE,CHK_TIME,IP_ADDRESS,MACHINE_NO,0 as totalSeconds,'N' as Delflag from users_CTE where row=1 
union all 
select t.row,t.USERID,t.USER_NAME,t.CHECKTIME,t.CHECKTYPE,t.VERIFYCODE,t.CHK_DATE,t.CHK_TIME,t.IP_ADDRESS,t.MACHINE_NO, 
CASE WHEN (c.totalSeconds + DATEDIFF(SECOND,c.CHECKTIME,t.CHECKTIME)) >= 60 then 0 else (c.totalSeconds + DATEDIFF(SECOND,c.CHECKTIME,t.CHECKTIME)) end as totalSeconds, 
CASE WHEN (c.totalSeconds + DATEDIFF(SECOND,c.CHECKTIME,t.CHECKTIME)) >= 60 then 'N' else 'Y' end as Delflag 
--CASE WHEN c.totalSeconds <= 60 then 'Y' else 'N' end as Delflag 
from users_CTE t inner join CTE c 
on t.row=c.row+1 
) 
INSERT INTO TempMachineData(USERID,USER_NAME,CHECKTIME,CHECKTYPE,VERIFYCODE,CHK_DATE,CHK_TIME,IP_ADDRESS,MACHINE_NO) 
select USERID,USER_NAME,CHECKTIME,CHECKTYPE,VERIFYCODE,CHK_DATE,CHK_TIME,IP_ADDRESS,MACHINE_NO from CTE 
WHERE Delflag='N' 

DELETE FROM daily_machine_data 
WHERE USER_NAME = 'HRA002' AND Convert(varchar(10),CHECKTIME,101) = Convert(varchar(10),GetDate(),101) 

INSERT INTO daily_machine_data(USERID,USER_NAME,CHECKTIME,CHECKTYPE,VERIFYCODE,CHK_DATE,CHK_TIME,IP_ADDRESS,MACHINE_NO) 
select USERID,USER_NAME,CHECKTIME,CHECKTYPE,VERIFYCODE,CHK_DATE,CHK_TIME,IP_ADDRESS,MACHINE_NO from TempMachineData 

DELETE FROM TempMachineData