2012-08-08 27 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