Fórum Select Com SUM() somando em duplicidade... #48826
11/01/2005
0
vamos ver se consigo explicar... se alguem tiver uma dica de como fazer essa consulta de forma mais pratica...
é que realmente só pensei nessa maneira...
tenho 3 tabelas
VENDA1 = ´CABEÇALHO DA VENDA´
VENDA = ´ITENS DA VENDA´
RECEBIMENTO = ´FORMAS DE PAGAMENTO / VALORES´
*********************** a consulta **************************
SELECT V1.ID_VENDA1,V1.ID_MECANICO,f.nome_funcionario AS mecanico,F.COMISSAO_funcionario,sum(R.VALOR_RECEBIMENTO)
,SUM(
CASE v.refe_produto WHEN ´OS´ THEN v.unitario_venda *qtd_venda
ELSE 0
END) +SUM(
CASE v.refe_produto WHEN ´PNOS´ THEN v.unitario_venda *qtd_venda
ELSE 0
END) AS SOMA_SERVICOS
FROM venda1 v1
LEFT JOIN RECEBIMENTO R ON (R.ID_VENDA1 = V1.ID_VENDA1)
LEFT JOIN venda v ON (v.id_venda1 = v1.id_venda1)
LEFT JOIN funcionario f ON (f.codigo = v1.id_mecanico)
AND V1.fechamento_venda1 BETWEEN ´01/10/05´ AND ´01/10/05´
AND v1.iD_mecanico = 43
GROUP BY V1.ID_VENDA1,V1.ID_MECANICO,f.nome,F.COMISSAO
ORDER BY F.nome
*********************** a consulta **************************
quando faço essa consulta... a SOMA DOS RECEBIMENTOS... vem em duplicidade.. ou seja... reparei que ela vem multiplicada pela quantidade de ITENS da tabela VENDA !!!
exemplo:
MECANICOCOMISSAOSUMSOMA_SERVICOS
FULANO 50¬ 4320160
onde: 4320 era pra ser 240... mas reparei que na VENDA existem 18 itens, ou seja, 4320/18 = 240...
reparem que preciso usar a tabela VENDA por causa do campo REFE_PRODUTO pro bando me dar apenas a soma para SOMA_SERVICOS quando o campo REFE_PRODUTO for IGUAL a ´OS´, etc...
espero ter deixado claro...
desde ja agradeço...
[]s
Seven
Curtir tópico
+ 0Posts
12/01/2005
Dbergkamps
Porque não descreve o tu quer que saia no relatório.
Gostei + 0
12/01/2005
Emerson Nascimento
SELECT V1.ID_VENDA1,V1.ID_MECANICO,f.nome_funcionario AS mecanico,
    F.COMISSAO_funcionario,
        (select sum(R.VALOR_RECEBIMENTO)
          from RECEBIMENTO R where R.ID_VENDA1 = V1.ID_VENDA1) AS VALOR_RECEBIMENTO,
    case v.refe_produto
        when ´OS´ then SUM(v.unitario_venda*v.qtd_venda)
        when ´PNOS´ then SUM(v.unitario_venda*v.qtd_venda)
    end as SOMA_SERVICOS
FROM venda1 v1
LEFT JOIN funcionario f ON (f.codigo = v1.id_mecanico)
LEFT JOIN venda v ON (v.id_venda1 = v1.id_venda1)
WHERE (V1.fechamento_venda1 BETWEEN ´01/10/05´ AND ´01/10/05´)
    AND v1.iD_mecanico = 43
GROUP BY V1.ID_VENDA1,V1.ID_MECANICO,f.nome_FUNCIONARIO,F.COMISSAO_FUNCIONARIO
ORDER BY F.nome
mas sinceramente não entendi o porque do case nesse exemplo. bastaria fazer:
SELECT V1.ID_VENDA1,V1.ID_MECANICO,f.nome_funcionario AS mecanico,
    F.COMISSAO_funcionario,
        (select sum(R.VALOR_RECEBIMENTO)
          from RECEBIMENTO R where R.ID_VENDA1 = V1.ID_VENDA1) AS VALOR_RECEBIMENTO,
    SUM(v.unitario_venda*v.qtd_venda) AS SOMA_SERVICOS
FROM venda1 v1
LEFT JOIN funcionario f ON (f.codigo = v1.id_mecanico)
LEFT JOIN venda v ON (v.id_venda1 = v1.id_venda1)
WHERE (V1.fechamento_venda1 BETWEEN ´01/10/05´ AND ´01/10/05´)
    AND v1.iD_mecanico = 43
GROUP BY V1.ID_VENDA1,V1.ID_MECANICO,f.nome_FUNCIONARIO,F.COMISSAO_FUNCIONARIO
ORDER BY F.nome
se você quiser calcular somente os valores de OS e PNOS, poderia fazer assim:
SELECT V1.ID_VENDA1,V1.ID_MECANICO,f.nome_funcionario AS mecanico,
    F.COMISSAO_funcionario,
        (select sum(R.VALOR_RECEBIMENTO)
          from RECEBIMENTO R where R.ID_VENDA1 = V1.ID_VENDA1) AS VALOR_RECEBIMENTO,
    SUM(v.unitario_venda*v.qtd_venda) AS SOMA_SERVICOS
FROM venda1 v1
LEFT JOIN funcionario f ON (f.codigo = v1.id_mecanico)
LEFT JOIN venda v ON (v.id_venda1 = v1.id_venda1 and v.refe_produto in (´OS´,´PNOS´))
WHERE (V1.fechamento_venda1 BETWEEN ´01/10/05´ AND ´01/10/05´)
    AND v1.iD_mecanico = 43
GROUP BY V1.ID_VENDA1,V1.ID_MECANICO,f.nome_FUNCIONARIO,F.COMISSAO_FUNCIONARIO
ORDER BY F.nome
se você quiser calcular somente os valores de OS, poderia fazer assim:
SELECT V1.ID_VENDA1,V1.ID_MECANICO,f.nome_funcionario AS mecanico,
    F.COMISSAO_funcionario,
        (select sum(R.VALOR_RECEBIMENTO)
          from RECEBIMENTO R where R.ID_VENDA1 = V1.ID_VENDA1) AS VALOR_RECEBIMENTO,
    SUM(v.unitario_venda*v.qtd_venda) AS SOMA_SERVICOS
FROM venda1 v1
LEFT JOIN funcionario f ON (f.codigo = v1.id_mecanico)
LEFT JOIN venda v ON (v.id_venda1 = v1.id_venda1 and v.refe_produto = ´OS´)
WHERE (V1.fechamento_venda1 BETWEEN ´01/10/05´ AND ´01/10/05´)
    AND v1.iD_mecanico = 43
GROUP BY V1.ID_VENDA1,V1.ID_MECANICO,f.nome_FUNCIONARIO,F.COMISSAO_FUNCIONARIO
ORDER BY F.nome
Fiz uma subselect para a tabela RECEBIMENTO para evitar a duplicidade no valor pago.
Gostei + 0
12/01/2005
Seven
vou tentar ser mais claro..
preciso usar o CASE... pq preciso saber o que foi ´OS´, e o que não foi...
quero saber quanto o mecanico tem de ´SERVIÇOS/OS´, e quanto ele deu de lucro em PEÇAS, entende !?
tive que fazer umas alterações na consulta....
olha só como ficou... porem tive que criar uma iBClientDataSet para poder agrupar pro mecanico os (VALOR_RECEBIMENTO) que continuaram multiplicando pela qtd de registros da tabela VENDA. a consulta ficou assim:
SELECT V1.ID_VENDA1,V1.ID_MECANICO,f.nome_funcionario AS mecanico,F.COMISSAO_funcionario
,(SELECT SUM(VALOR_RECEBIMENTO) FROM RECEBIMENTO WHERE RECEBIMENTO.ID_VENDA1 = V1.ID_VENDA1) AS F_2
,SUM(
CASE v.refe_produto WHEN ´OS´ THEN v.unitario_venda *qtd_venda
ELSE 0
END) AS SOMA_SERVICOS
,SUM(
CASE v.refe_produto WHEN ´PNOS´ THEN v.unitario_venda *qtd_venda
ELSE 0
END) AS SOMA_SERVICOS2
,SUM(
CASE v.refe_produto WHEN ´OSLAV´ THEN v.unitario_venda *qtd_venda
ELSE 0
END) AS SOMA_SERVICOS3
,SUM(
CASE v.refe_produto WHEN ´OS´ THEN qtd_venda
ELSE 0
END) AS QTD_SERVICOS
,SUM(
CASE v.refe_produto WHEN ´PNOS´ THEN qtd_venda
ELSE 0
END) AS QTD_SERVICOS2
,SUM(
CASE v.refe_produto WHEN ´OSLAV´ THEN qtd_venda
ELSE 0
END) AS QTD_SERVICOS3
FROM venda1 v1
LEFT JOIN venda v ON (v.id_venda1 = v1.id_venda1)
LEFT JOIN funcionario f ON (f.codigo = v1.id_mecanico)
AND V1.fechamento_venda1 BETWEEN ´01/10/05´ AND ´01/10/05´
AND v1.iD_mecanico = 43
GROUP BY V1.ID_VENDA1,V1.ID_MECANICO,f.nome_funcionario,F.COMISSAO_funcionario
ORDER BY F.nome_funcionario
se eu tiro o V1.ID_VENDA1 ele não AGRUPA e da a seguinte mensagem:
************************************************************
Invalid token.
Dynamic SQL Error.
SQL error code = -104.
Invalid expression in the select list (not contained in either an aggregate function or the GROUP BY clause).
************************************************************
Emerson, como também deu nessa consulta ... o mesmo erro descrito acima...
************************************************************
SELECT V1.ID_VENDA1,V1.ID_MECANICO,f.nome_funcionario AS mecanico,
F.COMISSAO_funcionario,
(select sum(R.VALOR_RECEBIMENTO)
from RECEBIMENTO R where R.ID_VENDA1 = V1.ID_VENDA1) AS VALOR_RECEBIMENTO,
case v.refe_produto
when ´OS´ then SUM(v.unitario_venda*v.qtd_venda)
when ´PNOS´ then SUM(v.unitario_venda*v.qtd_venda)
end as SOMA_SERVICOS
FROM venda1 v1
LEFT JOIN funcionario f ON (f.codigo = v1.id_mecanico)
LEFT JOIN venda v ON (v.id_venda1 = v1.id_venda1)
WHERE (V1.fechamento_venda1 BETWEEN ´01/10/05´ AND ´01/10/05´)
AND v1.iD_mecanico = 43
GROUP BY V1.ID_VENDA1,V1.ID_MECANICO,f.nome_FUNCIONARIO,F.COMISSAO_FUNCIONARIO
ORDER BY F.nome
************************************************************
[]´s
Gostei + 0
12/01/2005
Seven
vou tentar ser mais claro..
preciso usar o CASE... pq preciso saber o que foi ´OS´, e o que não foi...
quero saber quanto o mecanico tem de ´SERVIÇOS/OS´, e quanto ele deu de lucro em PEÇAS, entende !?
tive que fazer umas alterações na consulta....
olha só como ficou... porem tive que criar uma iBClientDataSet para poder agrupar pro mecanico os (VALOR_RECEBIMENTO) que continuaram multiplicando pela qtd de registros da tabela VENDA. a consulta ficou assim:
SELECT V1.ID_VENDA1,V1.ID_MECANICO,f.nome_funcionario AS mecanico,F.COMISSAO_funcionario
,(SELECT SUM(VALOR_RECEBIMENTO) FROM RECEBIMENTO WHERE RECEBIMENTO.ID_VENDA1 = V1.ID_VENDA1) AS F_2
,SUM(
CASE v.refe_produto WHEN ´OS´ THEN v.unitario_venda *qtd_venda
ELSE 0
END) AS SOMA_SERVICOS
,SUM(
CASE v.refe_produto WHEN ´PNOS´ THEN v.unitario_venda *qtd_venda
ELSE 0
END) AS SOMA_SERVICOS2
,SUM(
CASE v.refe_produto WHEN ´OSLAV´ THEN v.unitario_venda *qtd_venda
ELSE 0
END) AS SOMA_SERVICOS3
,SUM(
CASE v.refe_produto WHEN ´OS´ THEN qtd_venda
ELSE 0
END) AS QTD_SERVICOS
,SUM(
CASE v.refe_produto WHEN ´PNOS´ THEN qtd_venda
ELSE 0
END) AS QTD_SERVICOS2
,SUM(
CASE v.refe_produto WHEN ´OSLAV´ THEN qtd_venda
ELSE 0
END) AS QTD_SERVICOS3
FROM venda1 v1
LEFT JOIN venda v ON (v.id_venda1 = v1.id_venda1)
LEFT JOIN funcionario f ON (f.codigo = v1.id_mecanico)
AND V1.fechamento_venda1 BETWEEN ´01/10/05´ AND ´01/10/05´
AND v1.iD_mecanico = 43
GROUP BY V1.ID_VENDA1,V1.ID_MECANICO,f.nome_funcionario,F.COMISSAO_funcionario
ORDER BY F.nome_funcionario
se eu tiro o V1.ID_VENDA1 ele não AGRUPA e da a seguinte mensagem:
************************************************************
Invalid token.
Dynamic SQL Error.
SQL error code = -104.
Invalid expression in the select list (not contained in either an aggregate function or the GROUP BY clause).
************************************************************
Emerson, como também deu nessa consulta ... o mesmo erro descrito acima...
************************************************************
SELECT V1.ID_VENDA1,V1.ID_MECANICO,f.nome_funcionario AS mecanico,
F.COMISSAO_funcionario,
(select sum(R.VALOR_RECEBIMENTO)
from RECEBIMENTO R where R.ID_VENDA1 = V1.ID_VENDA1) AS VALOR_RECEBIMENTO,
case v.refe_produto
when ´OS´ then SUM(v.unitario_venda*v.qtd_venda)
when ´PNOS´ then SUM(v.unitario_venda*v.qtd_venda)
end as SOMA_SERVICOS
FROM venda1 v1
LEFT JOIN funcionario f ON (f.codigo = v1.id_mecanico)
LEFT JOIN venda v ON (v.id_venda1 = v1.id_venda1)
WHERE (V1.fechamento_venda1 BETWEEN ´01/10/05´ AND ´01/10/05´)
AND v1.iD_mecanico = 43
GROUP BY V1.ID_VENDA1,V1.ID_MECANICO,f.nome_FUNCIONARIO,F.COMISSAO_FUNCIONARIO
ORDER BY F.nome
************************************************************
[]´s
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)