これはトリッキーな作業であり、そして、あなたのテーブルには、多くのレコードが含まれている場合、パフォーマンスが悪くなることを良いチャンスがあります。その場合は、テーブルをパーティション化するフィールド(UserId
?)でバッチで更新を実行することを検討することがあります。
時間がUnpaidSpent
フィールドに休憩に費やし、その後、休憩のために0
にSpentHours
を設定し、あなたのテーブルが#taskRecord
と呼ばれる最初のコピーと仮定すると:
Update #taskRecord
Set UnpaidSpent = SpentHours
Where TaskName = 'Break Time';
Update #taskRecord
Set SpentHours = 0
Where TaskName = 'Break Time';
その後、我々はしている行を特定する必要があります未払いの時間がある毎日の最初の行(昼休みの行を除く)。その日に9.5時間の勤務時間をまだ積算していない場合は、未払額から有料の勤務時間に時間を移してください。
With runningTotalHours As (
Select UserID, WorkDateTime = WorkDate, WorkDate = Convert(date, WorkDate), SpentHours, UnpaidSpent, TaskName,
Sum(SpentHours + UnpaidSpent) Over (Partition By UserId, Convert(date, WorkDate)
Order By WorkDate
Rows Between Unbounded Preceding And Current Row) As RunningTotalAll,
Sum(SpentHours) Over (Partition By UserId, Convert(date, WorkDate)
Order By WorkDate
Rows Between Unbounded Preceding And Current Row) As RunningTotalPaid
from #taskRecord
Where TaskName <> 'Break Time'),
RowsWithUnpaidHours As (
Select UserID, WorkDateTime, WorkDate, SpentHours, UnpaidSpent, TaskName, RunningTotalAll, RunningTotalPaid,
Row_Number() Over (Partition By UserId, WorkDate Order By WorkDateTime) As RowNo
From runningTotalHours
Where UnpaidSpent <> 0)
Update RowsWithUnpaidHours
Set SpentHours = CASE WHEN RunningTotalAll < 9.5 Then SpentHours + UnpaidSpent
ELSE SpentHours + 9.5 - RunningTotalPaid END,
UnpaidSpent = CASE WHEN RunningTotalAll < 9.5 Then 0
ELSE UnpaidSpent - 9.5 + RunningTotalPaid END
Where RowNo = 1 And RunningTotalPaid <> 9.5;
一貫性を確保するために、これは毎日の最初の行のみを未払いの時間で更新します。しかし、1日の終わりに無給時間に複数の仕事をしていた人が、昼食時間を取った後に支払われると考えられる日があるかもしれません。したがって、それ以上の調整がないことを示す(0 row(s) affected)
が報告されるまで、上記のステートメントを複数回実行する必要があります。
'Where TaskName = '休憩時間' – JimmyB