none
Saldo Conta (Extrato) RRS feed

  • 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,


    sexta-feira, 28 de novembro de 2008 11:22

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 Snippet

    create 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 Saldo

    from mov_data a

    order by a.codigo

     

     

    Resultados 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     -100

    6     2    D    20081210 100     -200

    7     2    D    20081210 100     -300

    8     2    C    20081210 300      0

     

    esse exemplo também está em:

    http://emanuelmcdba.spaces.live.com/default.aspx

     

    sexta-feira, 28 de novembro de 2008 13:34
  • 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.

    sexta-feira, 28 de novembro de 2008 14:06
  • Tirando o case da sentença fica assim ó:

     

    Code Snippet

    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 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
    sexta-feira, 28 de novembro de 2008 14:10

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

    sexta-feira, 28 de novembro de 2008 12:28
  • 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 Snippet

    create 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 Saldo

    from mov_data a

    order by a.codigo

     

     

    Resultados 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     -100

    6     2    D    20081210 100     -200

    7     2    D    20081210 100     -300

    8     2    C    20081210 300      0

     

    esse exemplo também está em:

    http://emanuelmcdba.spaces.live.com/default.aspx

     

    sexta-feira, 28 de novembro de 2008 13:34
  • 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


    sexta-feira, 28 de novembro de 2008 13:48
  • O que vc quer saber é o saldo no dia?

    sexta-feira, 28 de novembro de 2008 13:51
  • Emanuel,

    Seu código ta quase 100%
    Só que quando eu lanço débito, ele ta somando e não subtraindo.
    sexta-feira, 28 de novembro de 2008 13:57
  • Agora deu certo!!!!

    Eu tinha uma valor negativo no banco.

    Agora funfou

    1    C    2008-11-27 00:00:00.000    200    200
    1    C    2008-11-27 00:00:00.000    200    400
    1    C    2008-11-27 00:00:00.000    150    550
    1    D    2008-11-27 00:00:00.000    100    450

    sexta-feira, 28 de novembro de 2008 14:00
  • 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.

    sexta-feira, 28 de novembro de 2008 14:06
  • Tirando o case da sentença fica assim ó:

     

    Code Snippet

    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 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
    sexta-feira, 28 de novembro de 2008 14:10
  • 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 ?

    sexta-feira, 16 de abril de 2010 21:33
  • 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.
    segunda-feira, 19 de abril de 2010 19:07