Usuário com melhor resposta
Soma errada no sql server

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- Tipo Alterado Alencar Gonzalez sexta-feira, 16 de outubro de 2009 23:51
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.comHash 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- Sugerido como Resposta Gustavo Maia Aguiar sábado, 17 de outubro de 2009 14:38
- Marcado como Resposta Alencar Gonzalez terça-feira, 20 de outubro de 2009 18:31
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.comHash 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- Sugerido como Resposta Gustavo Maia Aguiar sábado, 17 de outubro de 2009 14:38
- Marcado como Resposta Alencar Gonzalez terça-feira, 20 de outubro de 2009 18:31
-
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!