#sql #sql-server #cumulative-sum
#sql #sql-сервер #кумулятивная сумма
Вопрос:
У меня есть накопительная сумма, которую мне нужно отменить. Как мне это сделать в SQL Server?
Пример:
--- ------------------- -----
| id| date|value|
--- ------------------- -----
| J1|2016-10-01 11:45:30| 100|
| J1|2016-10-02 11:30:30| 200|
| J1|2016-10-05 16:20:00| 400|
| J9|2016-10-06 08:35:00| 800|
| J9|2016-10-07 01:20:00| 900|
--- ------------------- -----
Требуемый фрейм данных:
--- ------------------- ----- ---------
| id| date|value|non_cum_value|
--- ------------------- ----- ---------
| J1|2016-10-01 11:45:30| 100| 0|
| J1|2016-10-02 11:30:30| 200| 100|
| J1|2016-10-05 16:20:00| 400| 200|
| J9|2016-10-06 08:35:00| 800| 400|
| J9|2016-10-07 01:20:00| 900| 100|
--- ------------------- ----- ---------
Мой код:
select t1.id, t1.value, DIFFERENCE(t1.value) as 'cum_sum'
from @t t1
inner join @t t2 on t1.id >= t2.id
group by t1.id, t1.value
order by t1.id
Комментарии:
1. Я потерялся . , , в чем логика?
2. Если вам нужна фактическая накопительная сумма, логика ничем не отличается от того, как вы обычно это делаете; просто измените порядок
ORDER BY
отASC
доDESC
.
Ответ №1:
Хмммм . , , вы, кажется, хотите вычесть значение из «предыдущей» строки. Это было бы:
select t.*,
(t.value - lag(t.val) over (order by date)) as diff
from @t;
Я не уверен, почему у вас есть «кумулятивная сумма» в названии. Это не помогает мне понять, что вы пытаетесь сделать.
Ответ №2:
Другая возможность :
SELECT *, V - SUM(V) OVER(ORDER BY D ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)
FROM T
Предполагая, что проверенные данные :
CREATE TABLE T (ID CHAR(2), D DATE, V FLOAT);
INSERT INTO T VALUES
('J1', '2016-10-01 11:45:30', 100),
('J1', '2016-10-02 11:30:30', 200),
('J1', '2016-10-05 16:20:00', 400),
('J9', '2016-10-06 08:35:00', 800),
('J9', '2016-10-07 01:20:00', 900);