在同一个表中使用CASE进行合并

时间:2014-07-24 11:46:24

标签: sql sql-server

我正在使用SQL Server 2014。 我的桌子叫做TF,这就是我到目前为止所做的。

+-----------+------------+--------+--------------+
| IdProduct | Month      | Sales  | Accumulation |
+-----------+------------+--------+--------------+
| DSN101    | 01/01/2014 | 100    | ((1))        |
| DSN101    | 01/02/2014 | 50     | 50           |
| DSN101    | 01/03/2014 | 250    | 300          |
+-----------+------------+--------+--------------+

IdProduct是一个字符串
月份是日期
销售和积累是浮动的

累积列最初为null,我接下来做的不起作用,所以我将默认值设为1。 这是我更新表格并填写表格的方式:

GO
MERGE INTO dbo.TF as A
USING dbo.TF as P
ON (A.IdProduct = P.IdProduct and MONTH(P.Month)=MONTH(A.Month)-1 and YEAR(P.Month)=YEAR(A.Month))
WHEN MATCHED THEN
UPDATE SET A.Accumulation = CASE
    WHEN P.Accumulation Is not null then P.Accumulation+A.Sales-1
    WHEN MONTH(A.Month)=1 and not exists(select P.Sales) then A.Sales
END; 

所以起初这一切都不会明显,因为第一个null导致第二个null然后是第三个。 现在第一种情况正常,第二种情况没有,我只是不明白为什么 我尝试了很多组合而没有成功。我需要的是,每年的第一个月,累积列只等于销售栏 我理解我的代码会使每一行都找到前一行,但我不知道如何让它在1月份停止 请帮帮我!

1 个答案:

答案 0 :(得分:2)

您似乎希望accumulative包含列中值的累积总和。您不需要将其存储在表中,您可以从查询中获取它:

select tf.*, sum(sales) over (order by month) - sales
from tf;

- sales是因为积累似乎不包括当前月份的销售额。如果您只想要当前年份(merge声明建议的那一年),那么请添加partition by

select tf.*, sum(sales) over (partition by year(month) order by month) - sales
from tf;

而且,如果你真的想在表中包含它,那么这些是可更新的表达式:

with toupdate as (
      select tf.*, sum(sales) over (order by month) - sales as newval
      from tf
     )
update toupdate
    set accumulation = newval;