我有一个表格,可以根据用户名通过Time Machine存储员工的登记时间。如果员工多次打孔,那么他的签到记录会有多个记录,这两个记录之间只有几秒钟的时差。显然只有第一条记录才有效。所有其他条目都无效,必须从表中删除。如果我可以选择当前日期的员工的所有签到记录,我该怎么办?
数据库中的数据如下。
Username Checktime CheckType
HRA001 7/29/2012 8:16:44 AM Check-In
HRA001 7/29/2012 8:16:46 AM Check-In
HRA001 7/29/2012 8:16:50 AM Check-In
HRA001 7/29/2012 8:16:53 AM Check-In
答案 0 :(得分:1)
试试这个:
;WITH users_CTE as (
select rank() over (partition by Username order by Checktime) as rnk from users
)
DELETE FROM users_CTE where rnk <> 1
- 对于您的第二个要求,请尝试此查询
;WITH users_CTE as (
select *,rank() over (partition by Username order by Checktime) as rnk from users
)
,CTE2 as (select Username,MIN(CheckTime) as minTime,DATEADD(mi,1,MIN(CheckTime)) as maxTime from users_CTE
group by Username)
delete from users where Checktime in(
select c1.Checktime from users_CTE c1 left join CTE2 c2
on c1.Checktime > c2.minTime and c1.Checktime <= c2.maxTime
where c2.Username is not null and c1.Username in(
select c1.Username from users_CTE c1 left join CTE2 c2
on c1.Checktime > c2.minTime and c1.Checktime <= c2.maxTime
group by c1.Username,c2.Username
having COUNT(*) > 1))
- 对于您更改的要求请查看下面的查询
alter table users add flag varchar(2)
;WITH users_CTE as (
select *,rank() over (partition by Username order by Checktime) as rnk from users
)
,CTE2 as (select Username,MIN(CheckTime) as minTime,DATEADD(mi,1,MIN(CheckTime)) as maxTime from users_CTE
group by Username)
update u SET u.flag = 'd' from users_CTE u inner join (
select c1.Checktime from users_CTE c1 left join CTE2 c2
on c1.Checktime > c2.minTime and c1.Checktime <= c2.maxTime
where c2.Username is not null and c1.Username in(
select c1.Username from users_CTE c1 left join CTE2 c2
on c1.Checktime > c2.minTime and c1.Checktime <= c2.maxTime
group by c1.Username,c2.Username
having COUNT(*) > 1)) a
on u.Checktime=a.Checktime
- 使用DeletFlag检查最新查询
;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
答案 1 :(得分:0)
为什么不在将签入插入db之前验证签入。如果此用户存在任何签到,则在此日期与该日期之间,则不执行任何其他操作
答案 2 :(得分:0)
您应该能够按时间顺序排序所有记录,从每位员工的上一次减去最新时间,如果结果小于某个阈值,则删除最近时间的行。
答案 3 :(得分:0)
您可以按签入时间尝试按RANK记录,然后删除RANK大于1的每一位员工的所有记录。
答案 4 :(得分:0)
尝试此查询:从员工中删除employee.checkin(从员工中选择checkin(checkin)&gt; 1);
答案 5 :(得分:0)
答案 6 :(得分:0)
DELETE FROM timesheet
WHERE timesheetRecordId <>(
SELECT TOP 1 timesheetRecordId from timesheet
WHERE checkInDate=todaysDate AND employeeId=empId ORDER BY checkInTime ASC
)
AND checkInDate=today's date AND empolyeeId=empId;
答案 7 :(得分:0)
我认为您不能在同一语句的子查询中从Delete语句指定目标表。所以你不能用一个Delete语句来做。
您可以做的是编写存储过程。在您的存储过程中,您应该创建一个包含此查询返回的PK的临时表:
select cht.pkey
from CheckTimeTable as cht
where exists ( select pkey
from CheckTimeTable
where username = cht.userName
and checkType = 'check-IN'
and Checktime >= subtime(cht.Checktime, '0 0:0:15.000000')
and Checktime < cht.Checktime);
然后写另一个语句从原始表CheckTimeTable中删除这些PK。
请注意,上面的查询是针对MySQL的,因此您需要找到从DBMS的时间戳中减去15秒的方法。在MySQL中,它是这样做的:
subtime(cht.Checktime, '0 0:0:15.000000')
此查询将返回具有另一个CheckTime记录的CheckTime记录,该记录来自同一用户,类型为Check-In,并且比其自己的检查时间早15秒。