之前更新的T-SQL更新字段

时间:2013-03-01 05:05:07

标签: sql-server tsql sql-update sql-server-2012

我需要从之前的值的总和填充字段。 例如:

Id          Price           Total that i need     
----------- ------------  ---------
1           500             500
2           200             500+200 = 700
3           NULL            Because price is null put previous value = 700
4           300             SUM of previous row = 500+200+(calc to 700)+ 300 = 1700 
5           NULL            Because price is null put previous value = 1700  

请注意我不能使用变量。

我也在使用子查询,但不起作用(只返回非空的价格总和)。

可以实时更新价格(按游标记录)吗?

3 个答案:

答案 0 :(得分:0)

实际上,这是典型的任务calculating running totals

试试这个

create table #t(id int, price decimal(10,2), tot_sum decimal(10,2))

insert #t(id, price) values(1, 500)
insert #t(id, price) values(2, 200)
insert #t(id, price) values(3, NULL)
insert #t(id, price) values(4, 300)
insert #t(id, price) values(5, NULL)

update a
set tot_sum=gr.tot_sum
from #t a 
     join(select a.id, max(a.price) as price, sum(isnull(b.price, 0))+max(isnull(a.price,0)) as tot_sum
            from #t a 
                 left join #t b on b.id < a.id
            group by a.id) gr on a.id=gr.id

select * from #t t order by id


drop table #t

答案 1 :(得分:0)

你必须学习CTE。 公用表表达式(CTE)可以被认为是在单个SELECT,INSERT,UPDATE,DELETE或CREATE VIEW语句的执行范围内定义的临时结果集。

CTE类似于派生表,因为它不作为对象存储,并且仅在查询期间持续。与派生表不同,CTE可以是自引用的,并且可以在同一查询中多次引用。 CTE可用于:

  • 创建递归查询。有关更多信息,请参阅递归查询 使用公用表表达式。
  • 在不需要一般使用视图时替换视图; 也就是说,您不必将定义存储在元数据中。
  • 按照从标量子选择派生的列启用分组, 或者是一种不确定或具有外部的功能 访问。
  • 在同一语句中多次引用结果表。

答案 2 :(得分:0)

一个有趣的问题,即使有点不寻常。但它似乎可以解决。如果我没有遗漏任何东西,请按照以下方式进行操作。

  1. 以“正常”方式计算运行总计,即忽略空值(事实上,将它们视为0)。

  2. 从上一个结果集中,仅选择Price为空的行,并计算其运行总计的运行总计。

  3. 将第二个结果集中最接近的“正在运行的总计”添加到第一个集合中的每个运行总计。

  4. 这是我对上述内容的实现:

    WITH AllTotals AS (
      SELECT
        Id,
        Price,
        Total = SUM(Price) OVER (ORDER BY Id)
      FROM atable
    )
    , NullTotals AS (
      SELECT
        Id,
        Total = SUM(Total) OVER (ORDER BY Id)
      FROM AllTotals
      WHERE Price IS NULL
    )
    SELECT
      Id,
      Price,
      Total = Total + COALESCE((
        SELECT TOP (1) Total
        FROM NullTotals
        WHERE NullTotals.Id < AllTotals.Id
        ORDER BY Id DESC
      ), 0)
    FROM AllTotals
    ;
    

    您可以尝试此查询at SQL Fiddle