Erro na SQL com SUM()
Bom dia.
Tenho duas tabelas um de PEDIDO e outra de PEDIDOITEM.
PEDIDO
CODPEDIDO
CODVENDEDOR
DATA
VALORREVERTIDO
PEDIDOITEM
CODPEDIDOITEM
CODPEDIDO
CODPRODUTO
QTDE
TOTAL
EXEMPLO:
fiz uma VENDA que na tabela PEDIDOITEM salvo dois ITENS deste pedido.
dai montei uma SQL para somar VALORREVERTIDO(baseado na tabela PEDIDO e o TOTAL ( baseado na tabela PEDIDOITEM).
Dai oq acontece eh soma certo TOTAL mas a coluna VALORREVERTIDO ele soma mas soma como se fosse duas vezes.
Tipo vendi dois itens cada um a 10 = 20 , o valor revertido = 18, dai eu jogando esta SQL fica assim :
TOTAL = 20
VALORREVERTIDO = 36 e o certo seria 36
Estou utilizando Interbase 6 e D7. segue a SQL para analise.
Select Distinct(V.NomeCompleto) as Vendedor, SUM(P.ValorRevertido) as ValorRevertido,
SUM(I.Total) as Total from Pedido P
Left Join PedidoItem I on I.CodPedido = P.CodPedido
Left Join VendedorComprador V on V.CodVendedorComprador = P.CodVendedor
Where P.CodPedido = 891 Group By V.NomeCompleto, P.Desconto
Tenho duas tabelas um de PEDIDO e outra de PEDIDOITEM.
PEDIDO
CODPEDIDO
CODVENDEDOR
DATA
VALORREVERTIDO
PEDIDOITEM
CODPEDIDOITEM
CODPEDIDO
CODPRODUTO
QTDE
TOTAL
EXEMPLO:
fiz uma VENDA que na tabela PEDIDOITEM salvo dois ITENS deste pedido.
dai montei uma SQL para somar VALORREVERTIDO(baseado na tabela PEDIDO e o TOTAL ( baseado na tabela PEDIDOITEM).
Dai oq acontece eh soma certo TOTAL mas a coluna VALORREVERTIDO ele soma mas soma como se fosse duas vezes.
Tipo vendi dois itens cada um a 10 = 20 , o valor revertido = 18, dai eu jogando esta SQL fica assim :
TOTAL = 20
VALORREVERTIDO = 36 e o certo seria 36
Estou utilizando Interbase 6 e D7. segue a SQL para analise.
Select Distinct(V.NomeCompleto) as Vendedor, SUM(P.ValorRevertido) as ValorRevertido,
SUM(I.Total) as Total from Pedido P
Left Join PedidoItem I on I.CodPedido = P.CodPedido
Left Join VendedorComprador V on V.CodVendedorComprador = P.CodVendedor
Where P.CodPedido = 891 Group By V.NomeCompleto, P.Desconto
Walter Faria
Curtidas 0
Respostas
Diegotiemann
29/04/2009
VALORREVERTIDO = 36 e o certo seria 36
?????????
Mas não está certo? Ou eu não entadi a sua dúvida?
Dá uma olhada no grup by , o que tá fazendo aquela coluna de desconto ai?
GOSTEI 0
Walter Faria
29/04/2009
entao, deixa eu explicar melho ficou meio confuso mesmo:
Tipo vendi dois itens cada um a 10. TOTAL DO PEDIDO = 20.
Deste 20 ( total ) tem valor real da reversao .
VALORREVERTIDO = 18 ( pedido inteiro ).
dai eu jogando esta SQL fica assim :
TOTAL = 20
VALORREVERTIDO = 36 e o certo seria 36
O motivo do VALORREVERTIDO esta dando 36 e pq na PEDIDOITEM deste pedido tem dois ITENS . Nao sei o motivo que SUM() soma duas vezes.
OK
Obrigado.
Tipo vendi dois itens cada um a 10. TOTAL DO PEDIDO = 20.
Deste 20 ( total ) tem valor real da reversao .
VALORREVERTIDO = 18 ( pedido inteiro ).
dai eu jogando esta SQL fica assim :
TOTAL = 20
VALORREVERTIDO = 36 e o certo seria 36
O motivo do VALORREVERTIDO esta dando 36 e pq na PEDIDOITEM deste pedido tem dois ITENS . Nao sei o motivo que SUM() soma duas vezes.
OK
Obrigado.
GOSTEI 0
Diegotiemann
29/04/2009
VALORREVERTIDO = 36 e o certo seria 36
Continuo não entendendo essa linha
se VALORREVERTIDO está resultando 36 e o certo seria 36, qual o problema, se está voltando 36?
GOSTEI 0
Diegotiemann
29/04/2009
Acho que descobri o que você quis dizer e como resolver:
Você quis dizer o seguinte
18 não 36
o problema está no seu select, você está aplicando SUM() na coluna VALORREVERTIDO, é óbvio que vai somar o valor que lá se encontar pra cada iten na tabela de pedidos
tenta assim
Você quis dizer o seguinte
VALORREVERTIDO = 36 e o certo seria 18
18 não 36
o problema está no seu select, você está aplicando SUM() na coluna VALORREVERTIDO, é óbvio que vai somar o valor que lá se encontar pra cada iten na tabela de pedidos
tenta assim
Select Distinct(V.NomeCompleto) as Vendedor, P.ValorRevertido SUM(I.Total) as Total from Pedido P Left Join PedidoItem I on I.CodPedido = P.CodPedido Left Join VendedorComprador V on V.CodVendedorComprador = P.CodVendedor Where P.CodPedido = 891 Group By 1, 2
GOSTEI 0
Walter Faria
29/04/2009
Entao, bom dia
era isto mesmo, obrigado. Mas qdo monto esta sql:
na esta agrupando pelo VENDEDOR: EXEMPLO
ROGERIO 1000,00
ANDRE 500,00
ANDRE 300,00
eu queria assim :
ROGERIO 1000,00
ANDRE 800,00
Select Distinct(V.NomeCompleto) as Vendedor, P.ValorRevertido, P.Desconto, SUM(I.Total) as Total from Pedido P
Left Join PedidoItem I on I.CodPedido = P.CodPedido
Left Join VendedorComprador V on V.CodVendedorComprador = P.CodResponsavel
Where p.codpedido >= 890
Group By v.NomeCompleto, P.ValorRevertido, P.Desconto
era isto mesmo, obrigado. Mas qdo monto esta sql:
na esta agrupando pelo VENDEDOR: EXEMPLO
ROGERIO 1000,00
ANDRE 500,00
ANDRE 300,00
eu queria assim :
ROGERIO 1000,00
ANDRE 800,00
Select Distinct(V.NomeCompleto) as Vendedor, P.ValorRevertido, P.Desconto, SUM(I.Total) as Total from Pedido P
Left Join PedidoItem I on I.CodPedido = P.CodPedido
Left Join VendedorComprador V on V.CodVendedorComprador = P.CodResponsavel
Where p.codpedido >= 890
Group By v.NomeCompleto, P.ValorRevertido, P.Desconto
GOSTEI 0
Rjun
29/04/2009
SELECT NomeCompleto, SUM(I.Total) AS Total FROM Pedido P LEFT JOIN PedidoItem I ON I.CodPedido = P.CodPedido LEFT JOIN VendedorComprador V ON V.CodVendedorComprador = P.CodResponsavel WHERE p.codpedido >= 890 GROUP BY v.NomeCompleto
GOSTEI 0
Walter Faria
29/04/2009
Ficou faltando o campo VALORREVERTIDO
Montei a SQL baseado na sua e ficou assim :
ROGERIO 1000,00 900,00
ANDRE 500,00 480,00
ANDRE 300,00 280,00
e queria que ficasse assim :
ROGERIO 1000,00 900,00
ANDRE 800,00 760,00
SELECT
NomeCompleto,
SUM(I.Total) AS Total, p.ValorRevertido
FROM
Pedido P
LEFT JOIN
PedidoItem I ON I.CodPedido = P.CodPedido
LEFT JOIN
VendedorComprador V ON V.CodVendedorComprador = P.CodResponsavel
WHERE
p.codpedido >= 890
GROUP BY
v.NomeCompleto, p.ValorRevertido
Montei a SQL baseado na sua e ficou assim :
ROGERIO 1000,00 900,00
ANDRE 500,00 480,00
ANDRE 300,00 280,00
e queria que ficasse assim :
ROGERIO 1000,00 900,00
ANDRE 800,00 760,00
SELECT
NomeCompleto,
SUM(I.Total) AS Total, p.ValorRevertido
FROM
Pedido P
LEFT JOIN
PedidoItem I ON I.CodPedido = P.CodPedido
LEFT JOIN
VendedorComprador V ON V.CodVendedorComprador = P.CodResponsavel
WHERE
p.codpedido >= 890
GROUP BY
v.NomeCompleto, p.ValorRevertido
GOSTEI 0
Rjun
29/04/2009
SELECT NomeCompleto, SUM(I.Total) AS Total, SUM(p.ValorRevertido) FROM Pedido P LEFT JOIN PedidoItem I ON I.CodPedido = P.CodPedido LEFT JOIN VendedorComprador V ON V.CodVendedorComprador = P.CodResponsavel WHERE p.codpedido >= 890 GROUP BY v.NomeCompleto
GOSTEI 0
Walter Faria
29/04/2009
entao, obrigado por me ajudar.
mas executei esta SQL que vc passou e assim mesmo que eu quero, mas so que algo errado, deixa eu tentar te explicar :
tipo na SQL ta somando com : SUM(I.Total) AS Total pra pegar total do pedido. na tabela PEDIDOITEM de um pedido tem dois itens , dai ele soma certinho mas so que o VALORREVERTIDO ele soma duas vezes
e o campo VALORREVERTIDO esta na tabela PEDIDO. Nao sei se fui claro.
da ficou assim :
ROGERIO 1000,00 1800,00
ANDRE 800,00 760,00
teria que ficar assim:
ROGERIO 1000,00 900,00
ANDRE 800,00 760,00
mas executei esta SQL que vc passou e assim mesmo que eu quero, mas so que algo errado, deixa eu tentar te explicar :
tipo na SQL ta somando com : SUM(I.Total) AS Total pra pegar total do pedido. na tabela PEDIDOITEM de um pedido tem dois itens , dai ele soma certinho mas so que o VALORREVERTIDO ele soma duas vezes
e o campo VALORREVERTIDO esta na tabela PEDIDO. Nao sei se fui claro.
da ficou assim :
ROGERIO 1000,00 1800,00
ANDRE 800,00 760,00
teria que ficar assim:
ROGERIO 1000,00 900,00
ANDRE 800,00 760,00
GOSTEI 0
Rjun
29/04/2009
O que seria esse ´VALORREVERTIDO´? Você pode postar a estrutura da tabela?
GOSTEI 0
Walter Faria
29/04/2009
VALORREVERTIDO por exemplo a venda ( pedido ) 1000,00 dai este pedido a forma de pagto eh CARNE FINASA o cliente vai pagar 1000,00 no carne e a FINASA vai pagar para empresa A VISTA 900,00 por isso que eu coloco este campo na tabela PEDIDO.
Tipo qdo eu salvo o PEDIDO eu ja calculo o valor da reversao e gravo na TABELA PEDIDO O VALORREVERTIDO.
PEDIDO
CODPEDIDO
CODRESPONSAVEL
CODCLIENTE
DATA
VALORREVERTIDO
PEDIDOITEM
CODPEDIDOITEM
CODPEDIDO
CODPRODUTO
QTDE
TOTAL
VENDEDORCOMPRADOR
CODVENDEDORCOMPRADOR
NOMECOMPLETO
NOME
Tipo qdo eu salvo o PEDIDO eu ja calculo o valor da reversao e gravo na TABELA PEDIDO O VALORREVERTIDO.
PEDIDO
CODPEDIDO
CODRESPONSAVEL
CODCLIENTE
DATA
VALORREVERTIDO
PEDIDOITEM
CODPEDIDOITEM
CODPEDIDO
CODPRODUTO
QTDE
TOTAL
VENDEDORCOMPRADOR
CODVENDEDORCOMPRADOR
NOMECOMPLETO
NOME
GOSTEI 0
Lehapan
29/04/2009
Caro Walter,
veja se o SQL abaixo resolve o seu problema ou te ajuda.
espero ter ajudado.
veja se o SQL abaixo resolve o seu problema ou te ajuda.
SELECT vend.NomeCompleto, ped.ValorRevertido, ( SELECT SUM(PEDIT.Total) FROM PedidoItem pedit WHERE pedit.CodPedido = ped.CodPedido ) AS Total FROM PEDIDO ped LEFT OUTER JOIN VendedorComprador vend ON vend.CodVendedorComprador = ped.CodResponsavel WHERE ped.codpedido >= 890 GROUP BY vend.NomeCompleto, ped.ValorRevertido
espero ter ajudado.
GOSTEI 0
Walter Faria
29/04/2009
esta SQL nao agrupa por vendedor.
[/url]
[/url]
GOSTEI 0
Rjun
29/04/2009
Se você adicionar um SUM(ValorRevertido) no seu SELECT, não resolve seu problema?
GOSTEI 0
Walter Faria
29/04/2009
Resolveria, mas oq esta acontecendo que como estou somando a tabela PEDIDOITEM - SUM(I.TOTAL) , dai se eu colocar este SUM(VALORREVERTIDO) ele soma errado... como eu especificado acima.
SELECT
NomeCompleto,
SUM(I.Total) AS Total,
SUM(p.ValorRevertido)
FROM
Pedido P
LEFT JOIN
PedidoItem I ON I.CodPedido = P.CodPedido
LEFT JOIN
VendedorComprador V ON V.CodVendedorComprador = P.CodResponsavel
WHERE
p.codpedido >= 890
GROUP BY
v.NomeCompleto
com a esta SQL fica assim :
ROGERIO 1000,00 1800,00
ANDRE 800,00 760,00
teria que ficar assim:
ROGERIO 1000,00 900,00
ANDRE 800,00 760,00
SELECT
NomeCompleto,
SUM(I.Total) AS Total,
SUM(p.ValorRevertido)
FROM
Pedido P
LEFT JOIN
PedidoItem I ON I.CodPedido = P.CodPedido
LEFT JOIN
VendedorComprador V ON V.CodVendedorComprador = P.CodResponsavel
WHERE
p.codpedido >= 890
GROUP BY
v.NomeCompleto
com a esta SQL fica assim :
ROGERIO 1000,00 1800,00
ANDRE 800,00 760,00
teria que ficar assim:
ROGERIO 1000,00 900,00
ANDRE 800,00 760,00
GOSTEI 0
Jcfiora
29/04/2009
Walter, boa noite a voce e a todos os colegas aqui do fórum
Tive analisando o problema que voce apresentou aqui nesse tópico e a única
maneira que eu achei para resolver esse caso foi utilizar uma procedure selecionavel
e uma tabela auxiliar, se fosse outro banco voce poderia trabalhar com tabela
temporária, o que facilitaria bastante.Abaixo segue um script para voce criar a
tabela e a procedure, montei de acordo com os dados que voce informou na sua
estrutura de tabelas, nos testes que fiz aqui funcionou bem, mas vale a pena
conferir os nomes dos campos dentro da procedure para ver se de fato estão de
acordo com o seu banco de dados.
Caso voce queira tentar essa solução segue abaixo o script.
--***************************************************
--Início
--***************************************************
SET TERM ^;
--***************************************************
--CRIA UMA TABELA QUE VAI RECEBER DADOS TEMPORARIOS
--***************************************************
CREATE TABLE TT_VENDAS (
CODPEDIDO INTEGER,
VENDEDOR VARCHAR(90),
VALORREVERTIDO DECIMAL(18,2),
TOTAL DECIMAL(18,2)
);
--***************************************************
--CRIA PROCEDURE PARA SELECIONAR OS DADOS
--**************************************************-
CREATE OR ALTER PROCEDURE VENDAS (
CODPEDIDO INTEGER
)
RETURNS
(
NOME VARCHAR(90),
VALORREVERTIDO DECIMAL(18,2),
VALORTOTAL DECIMAL(18,2)
)
AS
DECLARE VARIABLE SQL VARCHAR(200);
BEGIN
-- Monta a Clásusula where do select inicial de pedidos.
-- Se o parâmetro for passado como 0 vai pegar todos os
-- pedidos
IF (:CODPEDIDO > 0) THEN
SQL = ´ WHERE P.CODPEDIDO = ´ || :CODPEDIDO ||
´ GROUP BY ´ ||
´ P.CODPEDIDO, ´ ||
´ V.NOMECOMPLETO ,´ ||
´ P.VALORREVERTIDO ´||
´ ORDER BY P.CODPEDIDO´;
ELSE
SQL = ´ GROUP BY ´ ||
´ P.CODPEDIDO, ´ ||
´ V.NOMECOMPLETO ,´ ||
´ P.VALORREVERTIDO ´||
´ ORDER BY P.CODPEDIDO´;
--Executa uma String contendo o camando SQL
--Insere na tabela temporária os dados do select
EXECUTE STATEMENT
´INSERT INTO TT_VENDAS ´ ||
´SELECT ´ ||
´ P.CODPEDIDO, ´ ||
´ V.NOMECOMPLETO AS VENDEDOR, ´ ||
´ P.VALORREVERTIDO, ´ ||
´ SUM(I.TOTAL) ´ ||
´FROM ´ ||
´ PEDIDO P ´ ||
´ LEFT JOIN PEDIDOITEM I ON ´ ||
´ I.CODPEDIDO = P.CODPEDIDO ´ ||
´ LEFT JOIN ´ ||
´ VENDEDORCOMPRADOR V ON ´ ||
´ V.CODVENDEDORCOMPRADOR = P.CODVENDEDOR´ ||
SQL;
--Faz o select na tabela temporária e retorna os valores selecionados.
FOR SELECT
TT.VENDEDOR,SUM(TT.VALORREVERTIDO), SUM(TT.TOTAL)
FROM
TT_VENDAS TT
GROUP BY
TT.VENDEDOR
INTO :NOME, :VALORREVERTIDO, :VALORTOTAL
DO
SUSPEND;
--Apaga os dados da tabela temporária
DELETE FROM TT_VENDAS;
END^
COMMIT^
SET TERM ; ^
--*******************************************************
--Fim
--*******************************************************
Tive analisando o problema que voce apresentou aqui nesse tópico e a única
maneira que eu achei para resolver esse caso foi utilizar uma procedure selecionavel
e uma tabela auxiliar, se fosse outro banco voce poderia trabalhar com tabela
temporária, o que facilitaria bastante.Abaixo segue um script para voce criar a
tabela e a procedure, montei de acordo com os dados que voce informou na sua
estrutura de tabelas, nos testes que fiz aqui funcionou bem, mas vale a pena
conferir os nomes dos campos dentro da procedure para ver se de fato estão de
acordo com o seu banco de dados.
Caso voce queira tentar essa solução segue abaixo o script.
--***************************************************
--Início
--***************************************************
SET TERM ^;
--***************************************************
--CRIA UMA TABELA QUE VAI RECEBER DADOS TEMPORARIOS
--***************************************************
CREATE TABLE TT_VENDAS (
CODPEDIDO INTEGER,
VENDEDOR VARCHAR(90),
VALORREVERTIDO DECIMAL(18,2),
TOTAL DECIMAL(18,2)
);
--***************************************************
--CRIA PROCEDURE PARA SELECIONAR OS DADOS
--**************************************************-
CREATE OR ALTER PROCEDURE VENDAS (
CODPEDIDO INTEGER
)
RETURNS
(
NOME VARCHAR(90),
VALORREVERTIDO DECIMAL(18,2),
VALORTOTAL DECIMAL(18,2)
)
AS
DECLARE VARIABLE SQL VARCHAR(200);
BEGIN
-- Monta a Clásusula where do select inicial de pedidos.
-- Se o parâmetro for passado como 0 vai pegar todos os
-- pedidos
IF (:CODPEDIDO > 0) THEN
SQL = ´ WHERE P.CODPEDIDO = ´ || :CODPEDIDO ||
´ GROUP BY ´ ||
´ P.CODPEDIDO, ´ ||
´ V.NOMECOMPLETO ,´ ||
´ P.VALORREVERTIDO ´||
´ ORDER BY P.CODPEDIDO´;
ELSE
SQL = ´ GROUP BY ´ ||
´ P.CODPEDIDO, ´ ||
´ V.NOMECOMPLETO ,´ ||
´ P.VALORREVERTIDO ´||
´ ORDER BY P.CODPEDIDO´;
--Executa uma String contendo o camando SQL
--Insere na tabela temporária os dados do select
EXECUTE STATEMENT
´INSERT INTO TT_VENDAS ´ ||
´SELECT ´ ||
´ P.CODPEDIDO, ´ ||
´ V.NOMECOMPLETO AS VENDEDOR, ´ ||
´ P.VALORREVERTIDO, ´ ||
´ SUM(I.TOTAL) ´ ||
´FROM ´ ||
´ PEDIDO P ´ ||
´ LEFT JOIN PEDIDOITEM I ON ´ ||
´ I.CODPEDIDO = P.CODPEDIDO ´ ||
´ LEFT JOIN ´ ||
´ VENDEDORCOMPRADOR V ON ´ ||
´ V.CODVENDEDORCOMPRADOR = P.CODVENDEDOR´ ||
SQL;
--Faz o select na tabela temporária e retorna os valores selecionados.
FOR SELECT
TT.VENDEDOR,SUM(TT.VALORREVERTIDO), SUM(TT.TOTAL)
FROM
TT_VENDAS TT
GROUP BY
TT.VENDEDOR
INTO :NOME, :VALORREVERTIDO, :VALORTOTAL
DO
SUSPEND;
--Apaga os dados da tabela temporária
DELETE FROM TT_VENDAS;
END^
COMMIT^
SET TERM ; ^
--*******************************************************
--Fim
--*******************************************************
GOSTEI 0