You can use WITH
nested to get the order and calculate the values:
WITH sequencia AS (
SELECT ROW_NUMBER() OVER(PARTITION BY r.emp_id ORDER BY r.mes) AS sequencia,
r.mes,
r.credito,
r.debito,
r.emp_id
FROM viewFluxo r
),
saldo AS (
SELECT s.sequencia,
s.mes,
s.credito,
s.debito,
s.emp_id,
CAST((s.credito - s.debito) AS NUMERIC(15, 2)) AS saldo
FROM sequencia s
WHERE s.sequencia = 1
UNION ALL
SELECT s.sequencia,
s.mes,
s.credito,
s.debito,
s.emp_id,
CAST((sal.saldo + (s.credito - s.debito)) AS NUMERIC(15, 2))
FROM saldo sal
INNER JOIN sequencia s ON s.sequencia = sal.sequencia + 1
AND s.emp_id = sal.emp_id
)
SELECT s.emp_id,
s.mes,
s.credito,
s.debito,
s.saldo
FROM saldo s
ORDER BY s.emp_id,
s.mes
OPTION(MAXRECURSION 0)
See working on SQL Fiddle.
If you do not want to use ROW_NUMBER
as a way to generate a sequence, you can convert the month into DATE
and use it to organize values:
WITH saldo AS (
SELECT vf.mes,
vf.credito,
vf.debito,
vf.emp_id,
CAST((vf.credito - vf.debito) AS NUMERIC(15, 2)) AS saldo
FROM viewFluxo vf
WHERE NOT EXISTS(SELECT 1
FROM viewFluxo vf2
WHERE vf2.emp_id = vf.emp_id
AND vf2.mes < vf.mes)
UNION ALL
SELECT vf.mes,
vf.credito,
vf.debito,
vf.emp_id,
CAST((sal.saldo + (vf.credito - vf.debito)) AS NUMERIC(15, 2))
FROM saldo sal
INNER JOIN viewFluxo vf ON CONVERT(DATE, vf.mes + '01', 120) = DATEADD(MONTH, 1, CONVERT(DATE, sal.mes + '01', 120))
AND vf.emp_id = sal.emp_id
)
SELECT s.emp_id,
s.mes,
s.credito,
s.debito,
s.saldo
FROM saldo s
ORDER BY s.emp_id,
s.mes
OPTION(MAXRECURSION 0)
See working on SQL Fiddle.
I used the following script to create and popular the table:
CREATE TABLE viewFluxo(mes VARCHAR(6),
credito NUMERIC(15, 2),
debito NUMERIC(15, 2),
emp_id VARCHAR(4));
INSERT INTO viewFluxo(mes, credito, debito, emp_id)
VALUES('201708', 0, 5000, '0001'),
('201709', 123.25, 5000, '0001'),
('201710', 0, 10000, '0001'),
('201711', 0, 10000, '0001'),
('201712', 0, 10000, '0001'),
('201801', 0, 10000, '0001'),
('201802', 0, 10000, '0001'),
('201803', 0, 10000, '0001'),
--
('201708', 3600, 900, '0002'),
('201709', 3600, 1350.75, '0002'),
('201710', 3600, 900, '0002'),
('201711', 3600, 2000, '0002'),
('201712', 3600, 750.25, '0002'),
('201801', 3600, 1009.9, '0002'),
('201802', 3600, 900, '0002'),
('201803', 3600, 900, '0002'),
('201804', 3600, 900, '0002');
Search the web for "running Totals". There are several articles that explain how to implement in SQL Server 2008.
– José Diz
Has any response helped solve the problem and can address similar questions from other users? If so, make sure to mark the answer as accepted. To do this just click on the left side of it (below the indicator of up and down votes).
– Sorack