Select SUM com Três ou mais tabelas - (Esta Multiplica Valor pelo Numero de Registros)

21/07/2014

0

Ola! Pessoal

Estou com um problema na geração de um SELECT com SUM com mais de 2 tabelas agrupadas, ele me retorno o valor total vezes o numero de registros como se eu não estivesse agrupando.

Para melhor ilustrar meu problema Exemplo a baixo:

Tabela Pedidos
ID Vlr_Total
1 80,00

Tabelas Pedidos_Faturas
ID_Pedido Valor Data
1 40,00 01/08/14
1 10,00 01/09/14
1 30,00 01/10/14

Tabelas Contas_Receber
ID_Pedido Valor Data
1 40,00 01/08/14
1 10,00 01/09/14
1 30,00 01/10/14

-----
>>Select 1 - Desta Forma o Sum esta Errado :

Select P.ID, Sum(PF.Valor) as PF_Total, Sum(CR.Valor) as CR_Total
From Pedidos P
inner Join pedidos_fatura CR on (PF.ID_Pedido=P.ID)
inner Join Contas_Receber CR on (CR.ID_Pedido=P.ID)
Group by P.ID

Retorna:
ID PF_Total CR_Total
1 240,00 240,00

>>Select 2 - Desta Forma da Certo:

Select P.ID,
(Select Sum(PF.Valor) From pedidos_fatura PF Where PF.ID_PEDIDO=P.ID) as PF_Total,
(Select Sum(CR.Valor) From Contas_Receber CR Where CR.ID_Pedido=P.ID) as CR_Total
From Pedidos P
Group By P.ID

Retorna:
ID PF_Total CR_Total
1 80,00 80,00

Já vi alguns tópicos aqui no site com este problema e a solução que deram foi a Select-2, mas gostaria de saber se é um bug do Firebird 2.5 ou realmente não é possível fazer o select-1 OU se estou errando algumas coisa.

Obrigado Pela atenção!
Lauro Dalpra

Lauro Dalpra

Responder

Post mais votado

01/08/2014

Buenas,

Está multiplicando porque basicamente o que acontece é que para o primeiro join (pedido com pedidos fatura) o banco retorna 3 registros. Para cada um destes 3 registros, o banco traz os tres registros da CONTAS_RECEBER porque todos satisfazem o critério de igualdade com o P.ID
Você tem um relacionamento entra a pedidos_fatura e o contas_receber ?
Segue exemplo, filtrando pela data para trazer o resultado corretamente.

SELECT P.ID, SUM(PF.VALOR) AS PF_TOTAL, SUM(CR.VALOR) AS CR_TOTAL
FROM PEDIDOS P
INNER JOIN PEDIDOS_FATURA PF ON (PF.ID_PEDIDO=P.ID)
INNER JOIN CONTAS_RECEBER CR ON (CR.ID_PEDIDO=P.ID AND PF.DATA = CR.DATA)
GROUP BY P.ID


Abraççç,
Renato

Renato Rubinho

Renato Rubinho
Responder

Mais Posts

06/08/2014

Lauro Dalpra

Buenas, RRubinho!

Muito Obrigada pela resposta!

Deu certo erra isso mesmo que eu precisava!
Responder

06/08/2014

Lauro Dalpra

Digo: MUITO OBRIGAD"OOOOOOO"!
Responder

03/09/2018

Sebastiao

Buenas,

Está multiplicando porque basicamente o que acontece é que para o primeiro join (pedido com pedidos fatura) o banco retorna 3 registros. Para cada um destes 3 registros, o banco traz os tres registros da CONTAS_RECEBER porque todos satisfazem o critério de igualdade com o P.ID
Você tem um relacionamento entra a pedidos_fatura e o contas_receber ?
Segue exemplo, filtrando pela data para trazer o resultado corretamente.

SELECT P.ID, SUM(PF.VALOR) AS PF_TOTAL, SUM(CR.VALOR) AS CR_TOTAL
FROM PEDIDOS P
INNER JOIN PEDIDOS_FATURA PF ON (PF.ID_PEDIDO=P.ID)
INNER JOIN CONTAS_RECEBER CR ON (CR.ID_PEDIDO=P.ID AND PF.DATA = CR.DATA)
GROUP BY P.ID


Abraççç,
Renato


Olá, tudo bem?
O Tópico é antigo mas estou com o mesmo problema e não estou conseguindo implementar da forma que vc disse.
A única diferença do meu código pro seu, é que estou fazendo assim.

select p.idProdutor, p.nome, p.nInsEst, SUM(sd.quant) AS totalDev, SUM(sr.quant), sd.produtorId, sd.graoid from produtor p
inner join secagemdevolucao sd on (sd.produtorId = p.idProdutor and sd.graoId = 2)
inner join secagemremessa sr on (sr.produtorId = p.idProdutor and sd.produtorId = sr.produtorId and sr.graoId = 2)

group by p.idProdutor

Mas continua multiplicando
Responder

04/09/2018

Emerson Nascimento

tente assim:
select sr.produtorId, p.nome, p.nInsEst, sr.graoId, SUM(sr.quant) totalRem, 0 totalDev
from secagemremessa sr
inner join produtor p on p.idProdutor = sr.produtorId
where sr.graoId = 2
group by sr.produtorId, p.nome, p.nInsEst, sr.graoId
union all
select sd.produtorId, p.nome, p.nInsEst, sd.graoId, 0 totalRem, SUM(sd.quant) totalDev
from secagemdevolucao sd
inner join produtor p on p.idProdutor = sd.produtorId
where sd.graoId = 2
group by sd.produtorId, p.nome, p.nInsEst, sd.graoId


se o "union all" não for suficiente para agrupar, tente assim:
select T.produtorId, p.nome, p.nInsEst, T.graoId, SUM(T.totalRem) Remessa, SUM(T.totalDev) Devolucao
from (
select produtorId, graoId, SUM(quant) totalRem, 0 totalDev
from secagemremessa
group by produtorId, graoId
union all
select produtorId, graoId, 0 totalRem, SUM(quant) totalDev
from secagemdevolucao
group by produtorId, graoId
) T
inner join produtor p on p.idProdutor = T.produtorId
where T.graoId = 2
group by T.produtorId, p.nome, p.nInsEst, T.graoId


ou assim:
select produtorId, nome, nInsEst, graoId, SUM(totalRem) Remessa, SUM(totalDev) Devolucao
from (
select sr.produtorId, p.nome, p.nInsEst, sr.graoId, SUM(sr.quant) totalRem, 0 totalDev
from secagemremessa sr
inner join produtor p on p.idProdutor = sr.produtorId
where sr.graoId = 2
group by sr.produtorId, p.nome, p.nInsEst, sr.graoId
union all
select sd.produtorId, p.nome, p.nInsEst, sd.graoId, 0 totalRem, SUM(sd.quant) totalDev
from secagemdevolucao sd
inner join produtor p on p.idProdutor = sd.produtorId
where sd.graoId = 2
group by sd.produtorId, p.nome, p.nInsEst, sd.graoId
) T
group by produtorId, nome, nInsEst, graoId

Responder

04/09/2018

Emerson Nascimento

tente assim:
select sr.produtorId, p.nome, p.nInsEst, sr.graoId, SUM(sr.quant) totalRem, 0 totalDev
from secagemremessa sr
inner join produtor p on p.idProdutor = sr.produtorId
where sr.graoId = 2
group by sr.produtorId, p.nome, p.nInsEst, sr.graoId
union
select sd.produtorId, p.nome, p.nInsEst, sd.graoId, 0 totalRem, SUM(sd.quant) totalDev
from secagemdevolucao sd
inner join produtor p on p.idProdutor = sd.produtorId
where sd.graoId = 2
group by sd.produtorId, p.nome, p.nInsEst, sd.graoId


se o "union" não for suficiente para agrupar, tente assim:
select T.produtorId, p.nome, p.nInsEst, T.graoId, SUM(T.totalRem) Remessa, SUM(T.totalDev) Devolucao
from (
select produtorId, graoId, SUM(quant) totalRem, 0 totalDev
from secagemremessa
group by produtorId, graoId
union
select produtorId, graoId, 0 totalRem, SUM(quant) totalDev
from secagemdevolucao
group by produtorId, graoId
) T
inner join produtor p on p.idProdutor = T.produtorId
where T.graoId = 2
group by T.produtorId, p.nome, p.nInsEst, T.graoId


ou assim:
select produtorId, nome, nInsEst, graoId, SUM(totalRem) Remessa, SUM(totalDev) Devolucao
from (
select sr.produtorId, p.nome, p.nInsEst, sr.graoId, SUM(sr.quant) totalRem, 0 totalDev
from secagemremessa sr
inner join produtor p on p.idProdutor = sr.produtorId
where sr.graoId = 2
group by sr.produtorId, p.nome, p.nInsEst, sr.graoId
union
select sd.produtorId, p.nome, p.nInsEst, sd.graoId, 0 totalRem, SUM(sd.quant) totalDev
from secagemdevolucao sd
inner join produtor p on p.idProdutor = sd.produtorId
where sd.graoId = 2
group by sd.produtorId, p.nome, p.nInsEst, sd.graoId
) T
group by produtorId, nome, nInsEst, graoId
Responder

Assista grátis a nossa aula inaugural

Assitir aula

Saiba por que programar é uma questão de
sobrevivência e como aprender sem riscos

Assistir agora

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar