Usuário com melhor resposta
Saldo Conta (Extrato)

Pergunta
-
Galera, vi alguns posts falando de como fazer, mais eu não consegui entender muito bem como utilizar as soluções propostas pela comunidade.
Posto aqui minha necessidade novamente.
Minha tabela é assim:
CREATE TABLE MOV_CONTA
CODIGO int IDENTITY(1,1) NOT NULL,
CODIGO_CONTA int NOT NULL,
TIPO char(1) NOT NULL,
DATA datetime NOT NULL,
VALOR float NOT NULL,
Preciso trazer uma view como no seguinte, trazendo o saldo atual dinamicamente
codigo, codigo_conta, tipo, data, valor, saldo_atual
---------------------------------------------------------------------
1 1 C 10/10/2008 100 100
2 1 C 11/10/2008 100 200
3 1 D 11/10/2008 -50 150
4 1 C 12/10/2008 -100 50
Tem como fazer isso ?
Gostaria de sabe como fazer, e entender a lógica por traz da solução.
Obrigado amigos,
NÊ
Respostas
-
Olá Nê,
para o seu caso, vc deve levar em consideração que os dados são agrupados por codigo_conta, e também deve considerar diferenciar as contas de '"C"(crédito) e "D"(débito), pois, provavelmente vc não possui os dados de "valor" no formato positivo e negativo, já que vc utiliza a flag "tipo" pra essa finalidade né.
Seguem um exemplo para os dois casos que levantei.
Code Snippetcreate
table mov_data(
codigo int identity,codigo_conta
int not null,tipo
char(1),data
datetime,valor
float)go
insert
into mov_data(codigo_conta,tipo,data,valor) values(1,'C','10/10/2008',100)insert
into mov_data(codigo_conta,tipo,data,valor) values(1,'C','10/10/2008',100)insert
into mov_data(codigo_conta,tipo,data,valor) values(1,'D','11/10/2008',50)insert
into mov_data(codigo_conta,tipo,data,valor) values(1,'D','12/10/2008',100)insert
into mov_data(codigo_conta,tipo,data,valor) values(2,'D','12/10/2008',100)insert
into mov_data(codigo_conta,tipo,data,valor) values(2,'D','12/10/2008',100)insert
into mov_data(codigo_conta,tipo,data,valor) values(2,'D','12/10/2008',100)insert
into mov_data(codigo_conta,tipo,data,valor) values(2,'C','12/10/2008',300)go
/* ##### Visualiza saldo #####*/
select
a.codigo,a.codigo_conta,a.tipo,a.data,a.valor, (select sum(b.valor) from (select codigo,codigo_conta,case when tipo = 'C' then valor else -valor end valor from mov_data) b where a.codigo>=b.codigo and a.codigo_conta=b.codigo_conta) as Saldofrom
mov_data aorder
by a.codigoResultados do select:
Cod CC Tipo Data Valor Saldo
1 1 C 20081010 100 100
2 1 C 20081010 100 200
3 1 D 20081110 50 150
4 1 D 20081210 100 50
5 2 D 20081210 100 -
1006 2 D 20081210 100
-2007 2 D 20081210 100
-3008 2 C 20081210 300 0
esse exemplo também está em:
http://emanuelmcdba.spaces.live.com/default.aspx
-
Nê, é o seguinte, isso está ocorrendo porque, no banco o valor de debito como negativo.Como na sentença existe um case que verifica a flag "tipo", se vc lança um valor como -50, a sentença faz vê que a flag é debito, entao nao é necessário o sinal de "-", resumindo, como é passado o valor já negativo, então o calculo faz -(-50) que na operação final vai somar.
Se vc utiliza uma flag na tabela, para diferenciar de débito ou crédito, então né é obrigatório vc passar o o valor como negativo ou positivo, mas se sua aplicação, insere os valores de debito como negativo, desconsidere o case da sentença.
-
Tirando o case da sentença fica assim ó:
Code Snippetselect
a.codigo,a.codigo_conta,a.tipo,convert(varchar(12),a.data,112) data,a.valor, (select sum(b.valor) from (select codigo,codigo_conta, valor from mov_data) b where a.codigo>=b.codigo and a.codigo_conta=b.codigo_conta) as Saldofrom
mov_data aorder
by a.codigo- Marcado como Resposta Nê Bighetti sexta-feira, 16 de abril de 2010 21:30
- Não Marcado como Resposta Nê Bighetti sexta-feira, 16 de abril de 2010 21:30
- Marcado como Resposta Nê Bighetti sexta-feira, 16 de abril de 2010 21:31
Todas as Respostas
-
Bom Dia,
Fiz um Webcast demonstrando como calcular o Saldo. Postei os códigos e o link para o webcast no meu blog. Consulte o link abaixo:
Dicas e Truques sobre consultas complexas no SQL Server
http://gustavomaiaaguiar.spaces.live.com/blog/cns!F4F5C630410B9865!162.entry
Por hora segue um código de exemplo:
Code Snippet-- Tabela de Lançamentos para exemplificar o Subtotal
CREATE TABLE tblLancamentos (
DataLancamento SMALLDATETIME,
ValorLancamento SMALLMONEY)
-- Insere os registros
INSERT INTO tblLancamentos VALUES ('20080623',100)
INSERT INTO tblLancamentos VALUES ('20080624',-250)
INSERT INTO tblLancamentos VALUES ('20080625',380)
INSERT INTO tblLancamentos VALUES ('20080626',200)
INSERT INTO tblLancamentos VALUES ('20080627',-300)
-- Listar o saldo automático
SELECT DataLancamento, ValorLancamento,
(SELECT SUM(ValorLancamento) FROM tblLancamentos
WHERE DataLancamento <= QE.DataLancamento) AS Saldo
FROM tblLancamentos AS QE[ ]s,
Gustavo
-
Olá Nê,
para o seu caso, vc deve levar em consideração que os dados são agrupados por codigo_conta, e também deve considerar diferenciar as contas de '"C"(crédito) e "D"(débito), pois, provavelmente vc não possui os dados de "valor" no formato positivo e negativo, já que vc utiliza a flag "tipo" pra essa finalidade né.
Seguem um exemplo para os dois casos que levantei.
Code Snippetcreate
table mov_data(
codigo int identity,codigo_conta
int not null,tipo
char(1),data
datetime,valor
float)go
insert
into mov_data(codigo_conta,tipo,data,valor) values(1,'C','10/10/2008',100)insert
into mov_data(codigo_conta,tipo,data,valor) values(1,'C','10/10/2008',100)insert
into mov_data(codigo_conta,tipo,data,valor) values(1,'D','11/10/2008',50)insert
into mov_data(codigo_conta,tipo,data,valor) values(1,'D','12/10/2008',100)insert
into mov_data(codigo_conta,tipo,data,valor) values(2,'D','12/10/2008',100)insert
into mov_data(codigo_conta,tipo,data,valor) values(2,'D','12/10/2008',100)insert
into mov_data(codigo_conta,tipo,data,valor) values(2,'D','12/10/2008',100)insert
into mov_data(codigo_conta,tipo,data,valor) values(2,'C','12/10/2008',300)go
/* ##### Visualiza saldo #####*/
select
a.codigo,a.codigo_conta,a.tipo,a.data,a.valor, (select sum(b.valor) from (select codigo,codigo_conta,case when tipo = 'C' then valor else -valor end valor from mov_data) b where a.codigo>=b.codigo and a.codigo_conta=b.codigo_conta) as Saldofrom
mov_data aorder
by a.codigoResultados do select:
Cod CC Tipo Data Valor Saldo
1 1 C 20081010 100 100
2 1 C 20081010 100 200
3 1 D 20081110 50 150
4 1 D 20081210 100 50
5 2 D 20081210 100 -
1006 2 D 20081210 100
-2007 2 D 20081210 100
-3008 2 C 20081210 300 0
esse exemplo também está em:
http://emanuelmcdba.spaces.live.com/default.aspx
-
Dessa maneira o saldo que aparece é o saldo total de todos os lançamentos,
preciso que o saldo seja mostrado por lançamento
data valor saldo
1/10 100 100
2/10 100 200
3/10 -50 150
4/10 -50 100
Repare que o saldo é mostrado de acordo com o lançamento, se eu lançar um credito de 200 agora
o saldo do lançamento vai para 300, o saldo do lançamento anterior não muda.
data valor saldo
1/10 100 100
2/10 100 200
3/10 -50 150
4/10 -50 100
5/10 200 300 -
-
-
-
Nê, é o seguinte, isso está ocorrendo porque, no banco o valor de debito como negativo.Como na sentença existe um case que verifica a flag "tipo", se vc lança um valor como -50, a sentença faz vê que a flag é debito, entao nao é necessário o sinal de "-", resumindo, como é passado o valor já negativo, então o calculo faz -(-50) que na operação final vai somar.
Se vc utiliza uma flag na tabela, para diferenciar de débito ou crédito, então né é obrigatório vc passar o o valor como negativo ou positivo, mas se sua aplicação, insere os valores de debito como negativo, desconsidere o case da sentença.
-
Tirando o case da sentença fica assim ó:
Code Snippetselect
a.codigo,a.codigo_conta,a.tipo,convert(varchar(12),a.data,112) data,a.valor, (select sum(b.valor) from (select codigo,codigo_conta, valor from mov_data) b where a.codigo>=b.codigo and a.codigo_conta=b.codigo_conta) as Saldofrom
mov_data aorder
by a.codigo- Marcado como Resposta Nê Bighetti sexta-feira, 16 de abril de 2010 21:30
- Não Marcado como Resposta Nê Bighetti sexta-feira, 16 de abril de 2010 21:30
- Marcado como Resposta Nê Bighetti sexta-feira, 16 de abril de 2010 21:31
-
Perfeitamente Emanuel.
Esta funcionando bem. Só que agora temos uma condição que gera erro.
Quando eu faço um lançamento com data retroativa, ele embanana o saldo, pois o registro é o último, mais o saldo deve ser calculado por data.Como fazer com que a ordem dos registros seja referenciada pela data do lançamento e não pelo código ?
-
Você tentou dar um ORDER BY por data? Algo como:
select a.codigo, a.codigo_conta, a.tipo, convert(varchar(12),a.data,112) data, a.valor, (select sum(b.valor) from ( select codigo,codigo_conta, valor from mov_data) b where a.codigo>=b.codigo and a.codigo_conta=b.codigo_conta) as Saldo from mov_data a order by data
Alexandre Baseio Se a minha ajuda lhe for útil não esqueça de classificar.