0

ユーザー名に基づいてTimeMachineを介した従業員のチェックイン時間を格納するテーブルがあります。従業員が複数回パンチした場合、チェックインの記録が複数あり、その間に数秒の時間差しかありません。明らかに、最初のレコードのみが有効です。他のすべてのエントリは無効であり、テーブルから削除する必要があります。現在の日付の従業員のすべてのチェックインレコードを選択できる場合、どうすればよいですか?

データベース内のデータは次のとおりです。

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 
4

8 に答える 8

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

--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)



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
于 2012-08-07T06:53:15.627 に答える
0

チェックイン時間までにレコードをランク​​付けしてから、RANKが1より大きい各日の各従業員のすべてのレコードを削除することができます。

于 2012-08-07T05:52:51.497 に答える
0

http://codesimplified.com/2010/10/18/remove-duplicate-records-from-the-database-table/

これがお役に立てば幸いです。

于 2012-08-07T06:01:32.000 に答える
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;
于 2012-08-07T06:15:43.970 に答える
0

チェックインをdbに挿入する前に確認してみませんか。この日付からその日付までの間に、このユーザーのチェックインが存在する場合は、他に何もしません。

于 2012-08-07T05:45:47.977 に答える
0

すべてのレコードを時間で並べ替え、従業員ごとの前回の時間から最新の時間を差し引き、結果が特定のしきい値未満の場合は、最新の時間の行を削除できるはずです。

于 2012-08-07T05:48:30.007 に答える
0

このクエリを試してください:employee.checkinの従業員から削除(count(checkin)> 1の従業員からチェックインを選択);

于 2012-08-07T05:57:49.157 に答える
0

同じステートメントのサブクエリで、Deleteステートメントからターゲットテーブルを指定することはできないと思います。したがって、1つの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レコードがあり、タイプがCheck-Inで、自身のチェックタイムより15秒以内のCheckTimeレコードを返します。

于 2012-08-07T08:29:30.930 に答える