Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Cesão

[Resolvido] Subtraindo soma de tabelas diferentes

Recommended Posts

Olá, amigos.

 

Tenho uma tabela onde tenho todos os pedidos efetuados pelos clientes e em outra tabela, tenho todos os depósitos feitos pelo cliente em uma conta pré-paga.

 

Gostaria de saber como subtrair a soma dos valores dos pedidos da soma dos depósitos efetuados pelo cliente para ter um saldo. O problema é que quando faço as somas num select relacionado das duas tabelas, a soma dos pedidos fica correta, mas a soma dos depósitos, não.

 

Parece que ele multiplica o valor da soma dos depósitos pelo número de pedidos. Por exemplo, se o cliente depositou 500 reais e fez 5 pedidos, ele mostra o total dos depósitos como 2500 reais.

 

Segue como está meu select:

SELECT SUM(a.NUM_VALOR_DEPOSITO) AS DEPOSITOS, SUM(b.NUM_VALOR_PEDIDO) AS PEDIDOS
FROM TBL_DEPOSITOS a
INNER JOIN TBL_PEDIDOS b ON a.ID_CLIENTE=b.ID_CLIENTE
WHERE a.ID_CLIENTE=1

Era para aparecer:

DEPOSITOS | PEDIDOS

500.00 | 253.00

 

Mas aparece:

DEPOSITOS | PEDIDOS

2500.00 | 253.00

Compartilhar este post


Link para o post
Compartilhar em outros sites

Aparentemente a expressão esta correta.

 

Sugiro que faça por partes:

SELECT SUM(a.NUM_VALOR_DEPOSITO) AS DEPOSITOS
FROM TBL_DEPOSITOS a
WHERE a.ID_CLIENTE=1

Se trouxer o valor correto vá completando.

 

Outra forma de fazer, menoso elegante seria:

DECLARE @DEPOSITOS DECIMAL(10,2), @PEDIDOS DECIMAL(10,2)
SELECT @DEPOSITOS = (SELECT SUM(a.NUM_VALOR_DEPOSITO) FROM TBL_DEPOSITOS a WHERE a.ID_CLIENTE=1)
SELECT @PEDIDOS = (SELECT SUM(b.NUM_VALOR_PEDIDO) AS PEDIDOS FROM TBL_PEDIDOS WHERE a.ID_CLIENTE=1)
SELECT @PEDIDOS - @DEPOSITOS 

Ou:

SELECT (SELECT SUM(a.NUM_VALOR_DEPOSITO) FROM @TBL_DEPOSITOS a WHERE a.ID_CLIENTE=1) AS DEPOSITOS, 
(SELECT SUM(b.NUM_VALOR_PEDIDO) FROM @TBL_PEDIDOS b WHERE B.ID_CLIENTE=1) AS PEDIDOS

 

Faça os teste e retorne.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Grande jothaz.

 

Então, da primeira forma é a que eu estava tentando... ir completando... mas não dava certo. Sempre que relacionava ele multiplicava o depósito pelo número de pedidos.

 

Na segunda (onde você usa variáveis), deu certo, mas você disse que não é a forma mais correta, certo? Ele perde em processamento?

 

A terceira forma ele passou os valores certos, mas não consegui fazer a conta de subtração a partir dela. Vi que é como se fossem dois selects separados mesmo, mas que você fez em um só. Essa seria a forma mais correta? Se for, como faço a subtração a partir dela?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Cesão,

 

Realmente usando o INNER JOIN repete e sinceramente não consegui enteder o porque. Estou meio enferrujado pois fiquei um bom tempo sem programar por motivo de saúde.

 

A idéia de variáveis para os puristas pode parecer menos elegante. Pelo que sei não vai afetar a performance mas você cria duas variáveis e a expressão fica maior. Eu particularmente sou bastante simplista e quando não dá para resolver de forma rebuscada vai na simplicidade memso. Portanto tirando o fato da expressão ficar um pouco maior não vejo problema algum em utilizá-la.

 

O pessoal aqui do fórum como mais experiência poderá questionar ou sugerir algo melhor.

 

Com relação aos dois select´s faça assim:

DECLARE @TBL_DEPOSITOS TABLE (ID_CLIENTE INT,NUM_VALOR_DEPOSITO DECIMAL(10,2))

DECLARE @TBL_PEDIDOS TABLE (ID_CLIENTE INT,NUM_VALOR_PEDIDO DECIMAL(10,2))

INSERT INTO @TBL_DEPOSITOS (ID_CLIENTE ,NUM_VALOR_DEPOSITO) VALUES (1,100)
INSERT INTO @TBL_DEPOSITOS (ID_CLIENTE ,NUM_VALOR_DEPOSITO) VALUES (1,100)
INSERT INTO @TBL_DEPOSITOS (ID_CLIENTE ,NUM_VALOR_DEPOSITO) VALUES (1,50)
INSERT INTO @TBL_DEPOSITOS (ID_CLIENTE ,NUM_VALOR_DEPOSITO) VALUES (2,10)

INSERT INTO @TBL_PEDIDOS (ID_CLIENTE ,NUM_VALOR_PEDIDO) VALUES (1,300)
INSERT INTO @TBL_PEDIDOS (ID_CLIENTE ,NUM_VALOR_PEDIDO) VALUES (1,50)
INSERT INTO @TBL_PEDIDOS (ID_CLIENTE ,NUM_VALOR_PEDIDO) VALUES (2,800)

SELECT (SELECT SUM(a.NUM_VALOR_DEPOSITO) FROM @TBL_DEPOSITOS a WHERE a.ID_CLIENTE=1) - 
(SELECT SUM(b.NUM_VALOR_PEDIDO) FROM @TBL_PEDIDOS b WHERE B.ID_CLIENTE=1) AS TOTAL

Compartilhar este post


Link para o post
Compartilhar em outros sites

Valeu Jothaz. Deu certo.

Das duas maneiras.. a com variávis, como você passou, e essa com dois selects um subtraindo o outro.

Vou usar essa segunda forma por enquanto, dos dois selects, pois acho que dá na mesma da com variáveis, mas economiza código!

 

Abraços e muito obtigado!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Opa, estou voltando este tópico, porque deu um problema.

 

Imaginemos que o cliente depositou 500 reais na conta dele e efetuou apenas um pedido de 10 reais. A soma final vai ser 490,00. beleza, isso dá certo.

O problema é quando o cliente não efetuou nem depósitos e nem efetuou compras. O PIOR AINDA é quando ele efetuou depósitos mas não efetuou compras. Em ambos os casos o resultado é NULL.

No primeiro caso, onde ele não efetuou depósitos nem compras, o resultado não deveria ser NULL, e sim, 0.00.

No segundo caso, onde ele efetuou um depósito de 500, mas não efetuou compras, o resultado deveria ser 500.00, mas está sendo NULL tbm.

 

Vcs sabem como fazer um IF ou algo assim p ele sempre trocar NULL por 0.00? Seja no resultado parcial ou total?

 

Meu select está assim:

SELECT (SELECT SUM(a.NUM_VALOR_DEPOSITO) FROM TBL_DEPOSITOS a WHERE a.ID_CLIENTE=1) - 
(SELECT SUM(b.NUM_VALOR_PEDIDO) FROM TBL_PEDIDOS b WHERE B.ID_CLIENTE=1) AS TOTAL

Compartilhar este post


Link para o post
Compartilhar em outros sites

Use ISNULL:

 

SELECT (SELECT isnull(SUM(a.NUM_VALOR_DEPOSITO),0) FROM @TBL_DEPOSITOS a WHERE a.ID_CLIENTE=1) - 
(SELECT isnull(SUM(b.NUM_VALOR_PEDIDO),0) FROM @TBL_PEDIDOS b WHERE B.ID_CLIENTE=1) AS TOTAL

Para mais detalhes: http://forum.imasters.com.br/index.php?/topic/225194-is-null-ou-isnull-eis-a-questao/

Compartilhar este post


Link para o post
Compartilhar em outros sites

Muito bom jothaz!! Funcionou certinho!! VOu ler o seu outro post que você mandou aí pra ver se aprendo mais.

Obrigado novamente!

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.