使用累积结果更新表记录

时间:2014-11-25 13:38:56

标签: sql sql-server tsql stored-procedures

假设我有一个表Tbl(表示为不同客户所做的工作的简单时间日志)

五列 Id:int TimeUse:浮动 IdCustomer:int 创建时间:DateTime TimeCalc:float

我在此表中有多条记录,(TimeCalc初始化为value = 0)

我希望我的SQL做的是:

当针对特定客户的所有前述记录的TimeUse累积到值<1时。 10然后TimeCalc中的值应为0

当特定客户的所有上述记录的TimeUse累积到值> = 10时,TimeCalc中的值应为= TimeUse for record ...

我使用子查询搞乱了Case例程,但无法使其正常工作。

BEFORE
    Id        TimeUse       IdCustomer        Created        TimeCalc
    1         2             1                 14/09/09       0
    2         5             2                 14/09/10       0
    3         2             1                 14/09/11       0
    4         5             2                 14/09/12       0
    5         4             1                 14/09/13       0
    6         2             2                 14/09/14       0
    7         4             1                 14/09/15       0
    8         1             1                 14/09/16       0
    9         3             2                 14/09/17       0
    10        2             1                 14/09/18       0
    11        4             2                 14/09/19       0



AFTER
    Id        TimeUse       IdCustomer        Created        TimeCalc
    1         2             1                 14/09/09       0
    2         5             2                 14/09/10       0
    3         2             1                 14/09/11       0
    4         5             2                 14/09/12       0
    5         4             1                 14/09/13       0
    6         2             2                 14/09/14       2
    7         4             1                 14/09/15       0
    8         1             1                 14/09/16       1
    9         3             2                 14/09/17       3 
    10        2             1                 14/09/18       2
    11        4             2                 14/09/19       4

这可以在SQL更新中解决吗?

1 个答案:

答案 0 :(得分:3)

在SQL Server 2012+中,您可以使用累积总和来执行此操作:

select Id, TimeUse, IdCustomer, Created,
       (case when sum(timeuse) over (partition by idcustomer order by id) < 10 then 0
             else timeuse
        end) as timecalc
from table t;

您可以使用outer apply或子查询在早期版本中执行相同的操作。

如果您想要更新,只需使用CTE:

with toupdate as (
      select t.*,
             (case when sum(timeuse) over (partition by idcustomer order by id) < 10 then 0
                   else timeuse
              end) as new_timecalc
      from table t
     )
update toupdate
    set timecalc = new_timecalc;

编辑:

以下内容适用于任何版本的SQL Server:

with toupdate as (
      select t.*,
             (case when (select sum(t2.timeuse)
                         from table t2
                         where t2.idcustomer = t.idcustomer and
                               t2.id <= t.id
                        ) < 10 then 0
                   else timeuse
              end) as new_timecalc
      from table t
     )
update toupdate
    set timecalc = new_timecalc;