SQL更新以前的记录

时间:2016-11-07 10:29:31

标签: sql sql-server database

我们有一张表,其中包含所有员工的任务记录。所需的花费时间是每天9.5(不包括午休时间),无论是非专利列中的超出时间。

之前,我们过去常常把午餐留空,但现在因为他们需要将午餐作为一项任务,所以午餐时间的小时/分钟包含在9.5所需的时间内。现在:

  1. 如何将breaktime值从花费转移到非花费?
  2. 更新后,我们如何扣除未支付的最后一个任务的休息时间,并将其移至spenthours以完成每天所需的9.5小时? 谢谢。
  3. enter image description here

2 个答案:

答案 0 :(得分:0)

这是一项棘手的任务,如果您的表包含许多记录,那么性能很可能会很差。如果是这种情况,那么您可以考虑通过对表进行分区的字段(UserId?)批量运行更新。

假设您的表名为#taskRecord,请先将休息时间用于UnpaidSpent字段,然后将SpentHours设置为0以便休息:

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;

为了确保一致性,这仅使用无薪时间更新每天的第一行。但有些日子里,一个人在一天结束时的无薪时间内完成了多项任务,现在可以在他们的午餐时间被删除后被视为已付款。因此,有必要多次运行上述语句,直到它报告(0 row(s) affected),表明不再需要进行调整。

答案 1 :(得分:-1)

UPDATE Your_table_name SET unpaid = spent
WHERE unpaid = 0 AND TaskName = 'Break Time'