none
Soma errada no sql server RRS feed

  • Pergunta

  • estou usando a seguinte instrução

    select

     

    distinct

    notas1

    .nroentsai,

    movest

    .orimovest,

    notas1

    .valtotentsai,

    notas

    .nomentsai

     

    --sum(notas1.valtotentsai) as total

    from

     

    dbo.notas1 notas1 left outer join

    dbo

    .movest movest on

    movest

    .orimovest = notas1.nroentsai inner join

    dbo

    .notas notas on

    notas

    .nroentsai = notas1.nroentsai

    where

     

    notas1.staiteentsai = 'A' and

    notas1

    .tipentsai = 50 and

    movest

    .tipmovest = 'NS' and

    notas1

    .codpro = 1 and

    movest

    .seqsubitepro = 10807

     

     

     


    ele me retorna o seguinte resultado (vou listar somente o campo valtotentsai para ser prático)

    19800,00
    6450,00
    1012,00
    3798,00
    1320,00
    5500,00
    1100,00
    17600,00
    220,00
    2110,00
    3798,00
    220,00
    660,00

    a soma desses valores é 63588,00

    agora se eu tento esta instrução


    select
    distinct

     

    --notas1.nroentsai,

     

    --movest.orimovest,

     

    --notas1.valtotentsai,

     

    --notas.nomentsai

     

    sum(notas1.valtotentsai) as total

    from

     

    dbo.notas1 notas1 left outer join

    dbo

    .movest movest on

    movest

    .orimovest = notas1.nroentsai inner join

    dbo

    .notas notas on

    notas

    .nroentsai = notas1.nroentsai

    where

     

    notas1.staiteentsai = 'A' and

    notas1

    .tipentsai = 50 and

    movest

    .tipmovest = 'NS' and

    notas1

    .codpro = 1 and

    movest

    .seqsubitepro = 10807

    a soma que o sql retornar é 70038,00


    alguem poderia me auxiliar nesta questão? por que o sql soma errado esta simples expressão?

    já tentei ver aqui no forum e não achei nada parecido.

    toda ajuda é bem vinda


    alguem poderia me auxiliar nesta questão? por que o sql soma errado esta simples expressão?

    já tentei ver aqui no forum e não achei nada parecido.

    toda ajuda é bem vinda

    sexta-feira, 16 de outubro de 2009 23:45

Respostas

  • Bom Dia,

    O SQL Server não "soma errado". Há um mal uso do DISTINCT e um interpretação errada do seu funcionamento. Veja que ao usar DISTINCT, você está eliminando as repetições e ao usar SUM não é possível eliminá-las e por isso o valor está a maior. Mesmo que você use o DISTINCT no SUM, lembre-se que o DISTINCT é aplicado ao final (após o SUM) e por isso mesmo usar DISTINCT em conjunto com cláusulas GROUP BY não tem o menor efeito. Se você deseja somar os registros sem repetições, vai ter que remontar o seu fluxo. Ex:

    select sum(valtotentsai) as total
    from (
    select distinct notas1.valtotentsai
    from
    dbo.notas1 notas1
    left outer join dbo.movest movest on movest.orimovest = notas1.nroentsai
    inner join dbo.notas notas on notas.nroentsai = notas1.nroentsai
    where
    notas1.staiteentsai = 'A' and notas1.tipentsai = 50 and
    movest.tipmovest = 'NS' and notas1.codpro = 1 and
    movest.seqsubitepro = 10807) as Q


    Vale a pena ressaltar que da forma que o seu LEFT OUTER JOIN está montado ele é ineficaz. Como você colocou uma cláusula WHERE referenciando a tabela MOVEST, o LEFT OUTER JOIN irá retornar o mesmo resultado que o INNER (porém fica mais lenta que esse).

    [ ]s,
     
    Gustavo Maia Aguiar
    http://gustavomaiaaguiar.spaces.live.com

    Hash Indexes – Uma implementação no SQL Server – Parte I
    http://gustavomaiaaguiar.spaces.live.com/blog/cns!F4F5C630410B9865!750.entry


    Classifique as respostas. O seu feedback é imprescindível
    sábado, 17 de outubro de 2009 14:38

Todas as Respostas

  • Bom Dia,

    O SQL Server não "soma errado". Há um mal uso do DISTINCT e um interpretação errada do seu funcionamento. Veja que ao usar DISTINCT, você está eliminando as repetições e ao usar SUM não é possível eliminá-las e por isso o valor está a maior. Mesmo que você use o DISTINCT no SUM, lembre-se que o DISTINCT é aplicado ao final (após o SUM) e por isso mesmo usar DISTINCT em conjunto com cláusulas GROUP BY não tem o menor efeito. Se você deseja somar os registros sem repetições, vai ter que remontar o seu fluxo. Ex:

    select sum(valtotentsai) as total
    from (
    select distinct notas1.valtotentsai
    from
    dbo.notas1 notas1
    left outer join dbo.movest movest on movest.orimovest = notas1.nroentsai
    inner join dbo.notas notas on notas.nroentsai = notas1.nroentsai
    where
    notas1.staiteentsai = 'A' and notas1.tipentsai = 50 and
    movest.tipmovest = 'NS' and notas1.codpro = 1 and
    movest.seqsubitepro = 10807) as Q


    Vale a pena ressaltar que da forma que o seu LEFT OUTER JOIN está montado ele é ineficaz. Como você colocou uma cláusula WHERE referenciando a tabela MOVEST, o LEFT OUTER JOIN irá retornar o mesmo resultado que o INNER (porém fica mais lenta que esse).

    [ ]s,
     
    Gustavo Maia Aguiar
    http://gustavomaiaaguiar.spaces.live.com

    Hash Indexes – Uma implementação no SQL Server – Parte I
    http://gustavomaiaaguiar.spaces.live.com/blog/cns!F4F5C630410B9865!750.entry


    Classifique as respostas. O seu feedback é imprescindível
    sábado, 17 de outubro de 2009 14:38
  • Boa tarde Gustavo.

    Obrigado por responer.

    Realmente o que interferia na soma era a clausula DISTINCT, porem ao utilizar o subselect a soma ainda estava errada, neste modo ele me retornou somente 11 registros, então tive que refazer tirando o distinct e limitando com mais uma condição.

    Quanto ao LEFT OUTER JOIN, tentei substituir pelo INNER (esta foi a minha primiera opção) e não deu certo. Infelizmente tive que usar a construção do LEFT OUTER JOIN com a limitação dos registros pela cláusula WHERE.

    Consegui o resultado esperado com a seguinte instrução: 
    Select sum(rs.valor) as total
    
    from 
    
    (select 
    
    notas1.valtotentsai as valor
    
    
    from
    
    dbo.movest movest left outer join 
    
    dbo.notas1 notas1 on 
    
    movest.orimovest = notas1.nroentsai 
    
    where
    
    notas1.staiteentsai = 'A' and
    
    notas1.tipentsai = 50 and
    
    notas1.codpro = 1 and
    
    movest.codpro = 1 and
    
    movest.seqsubitepro = 10807) as rs
    
    

    de outras maneiras sempre retornava um resultado diferente do desejado. 

    de qualquer maneira muito obrigado pela ajuda.

    Abraços!

    terça-feira, 20 de outubro de 2009 18:43