如何根据字段的总和更新记录,然后使用sum来计算sql中的新值

时间:2010-05-26 21:17:58

标签: sql sql-server cursor sum

以下是我试图通过迭代记录来做的事情。

如果可能,我希望有一个更优雅的解决方案,因为我确信这不是在sql中执行此操作的最佳方式。

set @counter = 1 

declare @totalhrs dec(9,3), @lastemp char(7), @othrs dec(9,3) 

while @counter <= @maxrecs 
begin 
  if exists(select emp_num from #tt_trans where id = @counter) 
  begin 
    set @nhrs = 0 
    set @othrs = 0 

    select @empnum = emp_num, @nhrs = n_hrs, @othrs = ot_hrs 
    from #tt_trans 
    where id = @counter 

    if @empnum = @lastemp 
    begin 
      set @totalhrs = @totalhrs + @nhrs 

      if @totalhrs > 40 
      begin 
        set @othrs = @othrs + @totalhrs - 40 
        set @nhrs = @nhrs - (@totalhrs - 40) 
        set @totalhrs = 40 
      end 
    end 
    else 
    begin 
       set @totalhrs = @nhrs 
       set @lastemp = @empnum 
    end 

    update #tt_trans 
    set n_hrs = @nhrs, 
        ot_hrs = @othrs 
    where id = @counter and can_have_ot = 1 
  end 

  set @counter = @counter + 1 
end

Thx

3 个答案:

答案 0 :(得分:1)

这很接近你想要的,但是一旦你回答我关于你真正想要实现的目标的评论,就需要稍微调整一下。

update #tt_trans 
    set n_hrs = CASE WHEN T2.totHrs>40 
                     THEN 40 
                     ELSE T2.totHrs END,
    ot_hrs= CASE WHEN T2.totHrs>40 
                 THEN T2.totHrs-40 
                 ELSE 0 END
FROM  #tt_trans trans T1
INNER JOIN (SELECT SUM(@nhrs) totHrs, EmpNum 
           FROM #tt_trans 
           WHERE can_have_ot=1 
           GROUP BY EmpNum) T2 ON (T1.EmpNum=T2.EmpNum)

WHERE can_have_ot = 1 

答案 1 :(得分:0)

看起来您正在进行迭代,因为您必须跟踪多个记录中给定员工的总小时数。您可以使用内部选择来汇总每个员工的小时数,并将该选择加入到您的#tt_trans表中。从该连接写下您的更新,并将您的逻辑放在更新列的CASE语句中。

答案 2 :(得分:0)

update #tt_trans
    set n_hrs = case 
    when t2.totHrs > 40
    then n_hrs - (t2.totHrs -40)
    else n_hrs
    end,
    ot_hrs = case 
    when t2.totHrs > 40 
    then ot_hrs + (t2.totHrs -40)
    else ot_hrs
    end
    from #tt_trans t1
    join (select sum (n_hrs) as totHrs, emp_num from #tt_trans where can_have_ot =1 group by emp_num) t2 on t1.emp_num = t2.emp_num where t1.post_date = (select max(post_date)from #tt_trans where emp_num = t1.emp_num)

基本上我修改了该期间最后一个日期的修改时间并进行了适当调整。感谢你们两位回应。这两个回复都把我引向我的。