Como obter saldo acumulado por linha no Postgres?
Prezados,
Estou precisando calcular os saldos diários de um determinado período em um extrato de conta-corrente. Como obter essa informação a partir de consulta SQL?
Vejamos:
Tenho uma consulta com a estrutura:
data_lancamento
debito_no_dia
credito_no_dia
(credito_no_dia - debito_no_dia) as saldo_no_dia
Na tabela acima, existem lançamentos em ALGUNS dias do período e preciso que no resultado aparecam TODOS os dias. Isso eu resolvi usando um inner join com generate_series, então agora, tenho um conjunto de registros com todos os dias do perído desejado...
Preciso de ajuda sobre como calcular o saldo ACUMULADO dos dias anteriores em cada linha do conjunto de registros. O resultado desejado seria algo do tipo:
data_lancamento debito_no_dia credito_no_dia saldo_no_dia saldo_cumulado
01/06/2011 100,00 200,00 100,00 100,00
02/06/2011 300,00 100,00 -200,00 -100,00
03/06/2011 -100,00
04/06/2011 -100,00
05/06/2011 0,00 400,00 400,00 300,00
Note que nos dias 03 e 04 não existe lançamentos na tabela, mas os dias foram criados pelo generate_series. Preciso saber como criar a coluna SALDO_ACUMULADO linha a linha que, em tese, é a soma do saldo_do_dia com o saldo_acumulado do dia anterior apresentado no recordset.
Esse formato é importante em meu aplicativo, porque, através dele consigo saber, por exemplo, em quantos e quais dias o saldo ficou negativo, possibilitando calcular o juro do cheque especial dia-a-dia e conferir com o valor cobrado pelo banco. Por isso preciso todos os dias e o saldo acumulado no final de cada dia, linha a linha.
Podem dar um exmplo de como implentar a solução na prática?
Grato,
Alexandre
Estou precisando calcular os saldos diários de um determinado período em um extrato de conta-corrente. Como obter essa informação a partir de consulta SQL?
Vejamos:
Tenho uma consulta com a estrutura:
data_lancamento
debito_no_dia
credito_no_dia
(credito_no_dia - debito_no_dia) as saldo_no_dia
Na tabela acima, existem lançamentos em ALGUNS dias do período e preciso que no resultado aparecam TODOS os dias. Isso eu resolvi usando um inner join com generate_series, então agora, tenho um conjunto de registros com todos os dias do perído desejado...
Preciso de ajuda sobre como calcular o saldo ACUMULADO dos dias anteriores em cada linha do conjunto de registros. O resultado desejado seria algo do tipo:
data_lancamento debito_no_dia credito_no_dia saldo_no_dia saldo_cumulado
01/06/2011 100,00 200,00 100,00 100,00
02/06/2011 300,00 100,00 -200,00 -100,00
03/06/2011 -100,00
04/06/2011 -100,00
05/06/2011 0,00 400,00 400,00 300,00
Note que nos dias 03 e 04 não existe lançamentos na tabela, mas os dias foram criados pelo generate_series. Preciso saber como criar a coluna SALDO_ACUMULADO linha a linha que, em tese, é a soma do saldo_do_dia com o saldo_acumulado do dia anterior apresentado no recordset.
Esse formato é importante em meu aplicativo, porque, através dele consigo saber, por exemplo, em quantos e quais dias o saldo ficou negativo, possibilitando calcular o juro do cheque especial dia-a-dia e conferir com o valor cobrado pelo banco. Por isso preciso todos os dias e o saldo acumulado no final de cada dia, linha a linha.
Podem dar um exmplo de como implentar a solução na prática?
Grato,
Alexandre
![Alexandre Thees Alexandre Thees](http://www.devmedia.com.br/imagens/fotoscolunistas/foto_alexandre.jpg)
Alexandre Thees
Curtidas 0
Respostas
![Jair N. Jair N.](http://www.devmedia.com.br/imagens/fotoscolunistas/Alfred E. Neuman.jpeg)
Jair N.
06/06/2011
Buonasera Alex, segue abaixo um exemplo "meio que esquisito" mas dá pra entender.....
Acaso, se for uma questão de praticidade criar uma view para saldos em períodos....
SELECT cc_extrado.data_lancamento
, my_periodo.data
, COALESCE (cc_extrado.debito_no_dia , 0) AS debito_no_dia
, COALESCE (cc_extrado.credito_no_dia, 0) AS credito_no_dia
,SUM (COALESCE (cc_extrado.credito_no_dia, 0) - COALESCE(cc_extrado.debito_no_dia , 0) ) AS saldo_no_dia
, (SELECT SUM(my_extrado.credito_no_dia - my_extrado.debito_no_dia)
FROM cc_extrado my_extrado
WHERE (my_extrado.data_lancamento <= my_periodo.data)) AS saldo_acumulado
FROM cc_extrado
RIGHT JOIN (SELECT (MIN(cc_extrado.data_lancamento) + GENERATE_SERIES(0,
(CAST (MAX(cc_extrado.data_lancamento) - MIN(cc_extrado.data_lancamento) AS INT)),1)) AS data
FROM cc_extrado) AS my_periodo
ON (my_periodo.data = cc_extrado.data_lancamento)
GROUP BY cc_extrado.data_lancamento
, cc_extrado.debito_no_dia
, cc_extrado.credito_no_dia
, my_periodo.data
ORDER BY my_periodo.data;
Acaso, se for uma questão de praticidade criar uma view para saldos em períodos....
SELECT cc_extrado.data_lancamento
, my_periodo.data
, COALESCE (cc_extrado.debito_no_dia , 0) AS debito_no_dia
, COALESCE (cc_extrado.credito_no_dia, 0) AS credito_no_dia
,SUM (COALESCE (cc_extrado.credito_no_dia, 0) - COALESCE(cc_extrado.debito_no_dia , 0) ) AS saldo_no_dia
, (SELECT SUM(my_extrado.credito_no_dia - my_extrado.debito_no_dia)
FROM cc_extrado my_extrado
WHERE (my_extrado.data_lancamento <= my_periodo.data)) AS saldo_acumulado
FROM cc_extrado
RIGHT JOIN (SELECT (MIN(cc_extrado.data_lancamento) + GENERATE_SERIES(0,
(CAST (MAX(cc_extrado.data_lancamento) - MIN(cc_extrado.data_lancamento) AS INT)),1)) AS data
FROM cc_extrado) AS my_periodo
ON (my_periodo.data = cc_extrado.data_lancamento)
GROUP BY cc_extrado.data_lancamento
, cc_extrado.debito_no_dia
, cc_extrado.credito_no_dia
, my_periodo.data
ORDER BY my_periodo.data;
Prezados,
Estou precisando calcular os saldos diários de um determinado período em um extrato de conta-corrente. Como obter essa informação a partir de consulta SQL?
Vejamos:
Tenho uma consulta com a estrutura:
data_lancamento
debito_no_dia
credito_no_dia
(credito_no_dia - debito_no_dia) as saldo_no_dia
Na tabela acima, existem lançamentos em ALGUNS dias do período e preciso que no resultado aparecam TODOS os dias. Isso eu resolvi usando um inner join com generate_series, então agora, tenho um conjunto de registros com todos os dias do perído desejado...
Preciso de ajuda sobre como calcular o saldo ACUMULADO dos dias anteriores em cada linha do conjunto de registros. O resultado desejado seria algo do tipo:
data_lancamento debito_no_dia credito_no_dia saldo_no_dia saldo_cumulado
01/06/2011 100,00 200,00 100,00 100,00
02/06/2011 300,00 100,00 -200,00 -100,00
03/06/2011 -100,00
04/06/2011 -100,00
05/06/2011 0,00 400,00 400,00 300,00
Note que nos dias 03 e 04 não existe lançamentos na tabela, mas os dias foram criados pelo generate_series. Preciso saber como criar a coluna SALDO_ACUMULADO linha a linha que, em tese, é a soma do saldo_do_dia com o saldo_acumulado do dia anterior apresentado no recordset.
Esse formato é importante em meu aplicativo, porque, através dele consigo saber, por exemplo, em quantos e quais dias o saldo ficou negativo, possibilitando calcular o juro do cheque especial dia-a-dia e conferir com o valor cobrado pelo banco. Por isso preciso todos os dias e o saldo acumulado no final de cada dia, linha a linha.
Podem dar um exmplo de como implentar a solução na prática?
Grato,
Alexandre
Estou precisando calcular os saldos diários de um determinado período em um extrato de conta-corrente. Como obter essa informação a partir de consulta SQL?
Vejamos:
Tenho uma consulta com a estrutura:
data_lancamento
debito_no_dia
credito_no_dia
(credito_no_dia - debito_no_dia) as saldo_no_dia
Na tabela acima, existem lançamentos em ALGUNS dias do período e preciso que no resultado aparecam TODOS os dias. Isso eu resolvi usando um inner join com generate_series, então agora, tenho um conjunto de registros com todos os dias do perído desejado...
Preciso de ajuda sobre como calcular o saldo ACUMULADO dos dias anteriores em cada linha do conjunto de registros. O resultado desejado seria algo do tipo:
data_lancamento debito_no_dia credito_no_dia saldo_no_dia saldo_cumulado
01/06/2011 100,00 200,00 100,00 100,00
02/06/2011 300,00 100,00 -200,00 -100,00
03/06/2011 -100,00
04/06/2011 -100,00
05/06/2011 0,00 400,00 400,00 300,00
Note que nos dias 03 e 04 não existe lançamentos na tabela, mas os dias foram criados pelo generate_series. Preciso saber como criar a coluna SALDO_ACUMULADO linha a linha que, em tese, é a soma do saldo_do_dia com o saldo_acumulado do dia anterior apresentado no recordset.
Esse formato é importante em meu aplicativo, porque, através dele consigo saber, por exemplo, em quantos e quais dias o saldo ficou negativo, possibilitando calcular o juro do cheque especial dia-a-dia e conferir com o valor cobrado pelo banco. Por isso preciso todos os dias e o saldo acumulado no final de cada dia, linha a linha.
Podem dar um exmplo de como implentar a solução na prática?
Grato,
Alexandre
GOSTEI 0
![Emerson Nascimento Emerson Nascimento](http://www.devmedia.com.br/imagens/fotoscolunistas/56986_20191018203443.jpg)
Emerson Nascimento
06/06/2011
como você não publicou a estrutura da sua tabela, vou trabalhar com a seguinte estrutura:
data
descricao
valor
tipo (debito ou credito)
onde os dados devem aparecer assim:
data descricao valor debito_credito
---------- -------------------- ---------- --------------
01.06.2011 dep. conta corrente 1.200,00 C
01.06.2011 pagto. conta luz 165,00 D
01.06.2011 pagto. conta agua 54,76 D
01.06.2011 pagto. fatura 600,00 D
02.06.2011 pagto. fatura 175,00 D
02.06.2011 recbtos. diversos 325,00 C
baseado nisso, creio que a instrução a seguir deva trazer as informações que você precisa:
SELECT
e.data,
coalesce(sum(case when e.tipo='C' then e.valor else 0 end), 0) credito_no_dia,
coalesce(sum(case when e.tipo='D' then e.valor else 0 end), 0) debito_no_dia,
coalesce(sum(e.valor * (case when e.tipo='D' then -1 else 1 end)), 0) saldo_no_dia,
(SELECT
coalesce(sum(e2.valor * (case when e2.tipo='D' then -1 else 1 end)), 0)
FROM
extrato e2
WHERE
e2.data <= e.data) acumulado
FROM
extrato e
WHERE
e.data between '01.06.2011' and '30.06.2011'
GROUP BY
e.data
ORDER BY
e.data
faça a adaptação para o seu modelo de dados.
data
descricao
valor
tipo (debito ou credito)
onde os dados devem aparecer assim:
data descricao valor debito_credito
---------- -------------------- ---------- --------------
01.06.2011 dep. conta corrente 1.200,00 C
01.06.2011 pagto. conta luz 165,00 D
01.06.2011 pagto. conta agua 54,76 D
01.06.2011 pagto. fatura 600,00 D
02.06.2011 pagto. fatura 175,00 D
02.06.2011 recbtos. diversos 325,00 C
baseado nisso, creio que a instrução a seguir deva trazer as informações que você precisa:
SELECT
e.data,
coalesce(sum(case when e.tipo='C' then e.valor else 0 end), 0) credito_no_dia,
coalesce(sum(case when e.tipo='D' then e.valor else 0 end), 0) debito_no_dia,
coalesce(sum(e.valor * (case when e.tipo='D' then -1 else 1 end)), 0) saldo_no_dia,
(SELECT
coalesce(sum(e2.valor * (case when e2.tipo='D' then -1 else 1 end)), 0)
FROM
extrato e2
WHERE
e2.data <= e.data) acumulado
FROM
extrato e
WHERE
e.data between '01.06.2011' and '30.06.2011'
GROUP BY
e.data
ORDER BY
e.data
faça a adaptação para o seu modelo de dados.
GOSTEI 0