Fórum SQL UNION E GROUPBY #506010
02/01/2015
0
USO INTERBASE 6.5.
Preciso fazer uma consulta SQL onde me retorne o valor da comissão do vendedor abatendo as devoluções feitas no mesmo período.
Segue SQL e o resultado obtido:
SELECT TAB026.nvendedor, Tab017.tdescricao, SUM(TAB027.ntotal * (TAB006.ncomissao)/100) as Comissao
FROM TAB017, TAB027, TAB026, TAB006
WHERE (Tab017.chave = Tab026.nvendedor)
AND (Tab027.nnumero = Tab026.chave)
AND (TAB027.nproduto = TAB006.nproduto)
AND (TAB027.ttabela = Tab006.tdescricao)
AND (Tab026.DDATA BETWEEN '29.12.2014 00:00' AND '29.12.2014 23:59')
AND tab026.nempresa = 1
AND TAB026.tcfop = '5.102'
AND tab026.ndocumentoprincipal IS NOT NULL
Group BY TAB026.nvendedor, Tab017.tdescricao
union
SELECT Tab026.nvendedor, TAB017.tdescricao,
(SUM(TAB083.ntotal * (TAB006.ncomissao)/100)*-1) as ComissaoDV
FROM tab082, TAB083, TAB026, TAB017, TAB006
where TAB082.chave = Tab083.nnumero
AND TAB026.chave = TAB082.npedido
AND TAB017.chave = TAB026.nvendedor
AND TAB006.tdescricao = TAB083.ttabela
AND TAB006.nproduto = TAB083.nproduto
AND (Tab082.DDATA BETWEEN '29.12.2014 00:00' AND '29.12.2014 23:59')
Group BY TAB026.nvendedor, Tab017.tdescricaoO Resultado:
[img:descricao=Resultado Sql]http://arquivo.devmedia.com.br/forum/imagem/404598-20150102-164437.png[/img]
Preciso que a coluna comissão tenha o resultado da comissão devida já descontando o valor negativo referente a devolução no período.
Agradeço desde já a ajuda.
Abraço
Roberto
Curtir tópico
+ 0Posts
03/01/2015
Alex Lekao
Acredito que teria uma forma melhor de fazer, mas vou tentar colocar algo para resolver mais rapidamente e assim vc testa e ve se atende, ai depois procura uma solucao mais adequada.
SELECT
NVENDEDOR,
TDESCRICAO,
SUM(COMISSAO) AS COMISSAO
FROM (
SELECT TAB026.nvendedor, Tab017.tdescricao, SUM(TAB027.ntotal * (TAB006.ncomissao)/100) as Comissao
FROM TAB017, TAB027, TAB026, TAB006
WHERE (Tab017.chave = Tab026.nvendedor)
AND (Tab027.nnumero = Tab026.chave)
AND (TAB027.nproduto = TAB006.nproduto)
AND (TAB027.ttabela = Tab006.tdescricao)
AND (Tab026.DDATA BETWEEN ''29.12.2014 00:00'' AND ''29.12.2014 23:59'')
AND tab026.nempresa = 1
AND TAB026.tcfop = ''5.102''
AND tab026.ndocumentoprincipal IS NOT NULL
Group BY TAB026.nvendedor, Tab017.tdescricao
union
SELECT Tab026.nvendedor, TAB017.tdescricao,
(SUM(TAB083.ntotal * (TAB006.ncomissao)/100)*-1) as Comissao
FROM tab082, TAB083, TAB026, TAB017, TAB006
where TAB082.chave = Tab083.nnumero
AND TAB026.chave = TAB082.npedido
AND TAB017.chave = TAB026.nvendedor
AND TAB006.tdescricao = TAB083.ttabela
AND TAB006.nproduto = TAB083.nproduto
AND (Tab082.DDATA BETWEEN ''29.12.2014 00:00'' AND ''29.12.2014 23:59'')
Group BY TAB026.nvendedor, Tab017.tdescricao
) AS TST
GROUP BY NVENDEDOR,TDESCRICAO,
Estou mais acostumado a fazer isso no SQL Server, nao sei se tem muita diferenca em relacao ao interbase, acho que nao, estou tomando o valor da comissao de devolucao como sendo apresentado negativamente(nao avaliei profundamente o codigo), mudei o nome para comissao para ficar igual ao do primeiro script.
Espero que ajude.
Abraco.
Gostei + 0
03/01/2015
Roberto
Infelizmente o Interbase não permite a Select dentro de outra Select. Eu tentei algo parecido antes e é retornado o erro na linha do segundo Select. Eu testei sua versão e não funcionou por esse motivo.
Obrigado pela ajuda mesmo assim.
Abraço
Gostei + 0
03/01/2015
Alex Lekao
Na pior das hipoteses crie uma view que faca esses selects seus e manipule a sua view no select, vc tera o mesmo resultado final, acredito eu. rsrsr
Abraco.
Gostei + 0
03/01/2015
Roberto
[img:descricao=Resultado Sql Alex]http://arquivo.devmedia.com.br/forum/imagem/404598-20150103-093351.png[/img]
Abraço
Gostei + 0
03/01/2015
Alex Lekao
Vamos tentar de outro jeito entao. rsrsr
Como vc precisaria que ficasse apresentado o relatorio?
Sugiro fazer subselects entao.
Gostei + 0
03/01/2015
Roberto
Preciso que a consulta resulte como a figura abaixo. Mas neste caso está sem o desconto da comissão negativa referente as devoluções. Como está no meu primeiro post.
[img:descricao=Esperado]http://arquivo.devmedia.com.br/forum/imagem/404598-20150103-102720.png[/img]
Valew...
Gostei + 0
03/01/2015
Alex Lekao
Gostei + 0
03/01/2015
Roberto
Gostei + 0
03/01/2015
Alex Lekao
Tente fazer o seguinte
Vamos ver se assim da certo, nao conseguindo pensar em algo melhor para te ajudar. rsrsr
Monte uma consulta dos vendedores e uma subconsulta referenciando o vendedor da consulta principal e um outra subtraindo as duas referenciando o vendeodr da prncipal.
Por exemplo:
SELECT
CODIGO,
VENDEDOR,
SUM((SELECT
SUM(TOTAL)
FROM VENDAS
WHERE VENDAS.CODIGO = VENDEDORES.CODIGO
AND DATA BETWEEN 'DATA INICIO' AND 'DATA FIM'
GROUP BY VENDAS.CODIGO,VENDAS.VENDEDOR)-
SELECT
SUM(TOTAL)
FROM DEVOLUCAO
WHERE VENDAS.CODIGO = VENDEDORES.CODIGO
AND DATA BETWEEN 'DATA INICIO' AND 'DATA FIM')
GROUP BY DEVOLUCAO.CODIGO,DEVOLUCAO.VENDEDOR) AS COMISSAO
FROM VENDEDORES
GROUP BY CODIGO,VENDEDOR
Costumo fazer algumas assim no SQL Server e da certo, vamos ver se dara certo para vc, fica mais pesado, mas nao to conseguindo elaborar nada mais sofisiticado e performatico no momento. rsrsr
Abraco.
Gostei + 0
03/01/2015
Marisiana Battistella
Todas as tabelas possuem ligações entre elas que permitem criar um único select para retornar as informações que você precisa.
Veja um exemplo que fiz com base na estrutura q vc apresentou na questão inicial:
SELECT res.nvendedor,
res.tdescricao,
(res.comissao - res.comissao2) as comissao
FROM (
SELECT TAB026.nvendedor,
Tab017.tdescricao,
SUM(TAB027.ntotal * (TAB006.ncomissao)/100) as Comissao,
(SUM(TAB083.ntotal * (TAB006.ncomissao)/100) * - 1) as Comissao2
FROM TAB017
INNER JOIN TAB026
ON Tab017.chave = Tab026.nvendedor
INNER JOIN TAB027
ON Tab027.nnumero = Tab026.chave
AND TAB027.ttabela = Tab006.tdescricao
INNER JOIN TAB006
ON TAB006.nproduto = TAB027.nproduto
INNER JOIN TAB083
ON TAB083.ttabela = TAB006.tdescricao
AND TAB083.nproduto = TAB006.nproduto
INNER JOIN tab082
ON TAB082.chave = Tab083.nnumero
AND TAB082.npedido = TAB026.chave
INNER JOIN TAB017
ON TAB017.chave = TAB026.nvendedor
WHERE Tab026.DDATA BETWEEN ''29.12.2014 00:00'' AND ''29.12.2014 23:59''
AND Tab082.DDATA BETWEEN ''29.12.2014 00:00'' AND ''29.12.2014 23:59''
AND tab026.nempresa = 1
AND TAB026.tcfop = ''5.102''
AND tab026.ndocumentoprincipal IS NOT NULL
Group BY TAB026.nvendedor,
Tab017.tdescricao
) res
GROUP BY res.nvendedor,
res.tdescricao
A menos que exista alguma condição especial a ser atendida e q, por isso, precise fazer o selects separados, pode ser q a minha idéia atenda a necessidade.
Gostei + 0
03/01/2015
Roberto
Obrigado bom final de semana.
Abraço
Gostei + 0
04/01/2015
Marisiana Battistella
SELECT TAB026.nvendedor,
Tab017.tdescricao,
SUM(TAB027.ntotal * (TAB006.ncomissao)/100) as Comissao,
(SUM(TAB083.ntotal * (TAB006.ncomissao)/100) * - 1) as Comissao2,
( SUM(TAB027.ntotal * (TAB006.ncomissao)/100) - (SUM(TAB083.ntotal * (TAB006.ncomissao)/100) * - 1) ) as resultado
FROM TAB017
INNER JOIN TAB026
ON Tab017.chave = Tab026.nvendedor
INNER JOIN TAB027
ON Tab027.nnumero = Tab026.chave
AND TAB027.ttabela = Tab006.tdescricao
INNER JOIN TAB006
ON TAB006.nproduto = TAB027.nproduto
INNER JOIN TAB083
ON TAB083.ttabela = TAB006.tdescricao
AND TAB083.nproduto = TAB006.nproduto
INNER JOIN tab082
ON TAB082.chave = Tab083.nnumero
AND TAB082.npedido = TAB026.chave
INNER JOIN TAB017
ON TAB017.chave = TAB026.nvendedor
WHERE Tab026.DDATA BETWEEN ''''29.12.2014 00:00'''' AND ''''29.12.2014 23:59''''
AND Tab082.DDATA BETWEEN ''''29.12.2014 00:00'''' AND ''''29.12.2014 23:59''''
AND tab026.nempresa = 1
AND TAB026.tcfop = ''''5.102''''
AND tab026.ndocumentoprincipal IS NOT NULL
Group BY TAB026.nvendedor,
Tab017.tdescricao
Só tem q ver se funciona...
Gostei + 0
05/01/2015
Roberto
A Consulta
SELECT TAB026.nvendedor, TAB017.tdescricao,
SUM(TAB027.ntotal * (TAB006.ncomissao)/100) as Comissao,
(SUM(TAB083.ntotal * (TAB006.ncomissao)/100) * - 1) as ComissaoDev,
(SUM(TAB027.ntotal * (TAB006.ncomissao)/100) -
(SUM(TAB083.ntotal * (TAB006.ncomissao)/100) * - 1) ) as resultado
FROM TAB017
INNER JOIN TAB026 ON TAB017.chave = TAB026.nvendedor
INNER JOIN TAB027 ON Tab027.nnumero = TAB026.chave
INNER JOIN TAB006 ON TAB006.nproduto= TAB027.nproduto AND TAB006.tdescricao = TAB027.ttabela
INNER JOIN TAB083 ON TAB083.ttabela = TAB006.tdescricao AND TAB083.nproduto = TAB006.nproduto
INNER JOIN TAB082 ON TAB082.chave = TAB083.nnumero
INNER JOIN TAB017 ON TAB017.chave = TAB026.nvendedor
WHERE TAB026.DDATA BETWEEN '29.12.2014 00:00' AND '29.12.2014 23:59'
AND TAB082.ddata BETWEEN '29.12.2014 00:00' AND '29.12.2014 23:59'
AND TAB026.nempresa = 1
AND TAB026.tcfop = '5.102/P'
AND TAB026.ndocumentoprincipal IS NOT NULL
Group BY TAB026.nvendedor, TAB017.tdescricaoEu retirei essa ligação entre as tabelas
TAB082.npedido = TAB026.chave
Pois se eu deixar o Resultado da consulta é NULL.
Bom retirando essa ligação foi dado o seguinte resultado:
[img:descricao=Consulta Alterada]http://arquivo.devmedia.com.br/forum/imagem/404598-20150105-093302.png[/img]
Está com os valores muito abaixo do que se é esperado pois o filtro de datas está determinando isso nesta parte do script:
AND TAB082.ddata BETWEEN '29.12.2014 00:00' AND '29.12.2014 23:59'
Essa TAB082 são só as devoluções geradas. E eu quero resgatar só se houver essas devoluções no período selecionado e não que ela seja um filtro que impeça que os pedidos gerados na TAB027 não sejam listados se não estiverem na TAB082. (Não sei se eu expliquei corretamente rsrsrs).
No entanto o que eu constatei é que a TAB083 que são os produtos das devoluções, essa não possui um campo de DATA. Dependendo da TAB082 para que eu possa setar esse periodo. Diferente do que ocorre com a TAB027 que são os produtos dos pedidos, essa possui um campo data que une ela a TAB026.
Resumindo, se eu deixar o código abaixo o resultado é muito menor do que o esperado para o RESULTADO.
AND TAB082.ddata BETWEEN '29.12.2014 00:00' AND '29.12.2014 23:59'
...Se eu retirar esse código acima o RESULTADO é muito alem do esperado. Penso eu porque falta a ligação entre a TAB026 E A TAB082 mas se eu há fizer o resultado da consulta é NULL. Não sei mais o que fazer.
Muito obrigado pela ajuda de vocês e pelo tempo que estão me disponibilizando.
Forte Abraço
Tenham uma semana abençoada!
Gostei + 0
05/01/2015
Marisiana Battistella
Pelo que entendi são as tabelas TAB083 e TAB082
SELECT TAB026.nvendedor, TAB017.tdescricao,
SUM(TAB027.ntotal * (TAB006.ncomissao)/100) as Comissao,
(SUM(TAB083.ntotal * (TAB006.ncomissao)/100) * - 1) as ComissaoDev,
(SUM(TAB027.ntotal * (TAB006.ncomissao)/100) -
(SUM(TAB083.ntotal * (TAB006.ncomissao)/100) * - 1) ) as resultado
FROM TAB017
INNER JOIN TAB026 ON TAB017.chave = TAB026.nvendedor
INNER JOIN TAB027 ON Tab027.nnumero = TAB026.chave
INNER JOIN TAB006 ON TAB006.nproduto= TAB027.nproduto AND TAB006.tdescricao = TAB027.ttabela
LEFT JOIN TAB083 ON TAB083.ttabela = TAB006.tdescricao AND TAB083.nproduto = TAB006.nproduto
LEFT JOIN TAB082 ON TAB082.chave = TAB083.nnumero
INNER JOIN TAB017 ON TAB017.chave = TAB026.nvendedor
WHERE TAB026.DDATA BETWEEN '29.12.2014 00:00' AND '29.12.2014 23:59'
AND TAB082.ddata BETWEEN '29.12.2014 00:00' AND '29.12.2014 23:59'
AND TAB026.nempresa = 1
AND TAB026.tcfop = '5.102/P'
AND TAB026.ndocumentoprincipal IS NOT NULL
Group BY TAB026.nvendedor, TAB017.tdescricaoEu não conheço a estrutura das tabelas, mas aconselho a verificar quais são as ligações entre elas (FK e PK) para ver se não falta incluir alguma delas.
Por exemplo: Existe algum relacionamento direto entre a TAB027 e a TAB082?
Gostei + 0
05/01/2015
Alex Lekao
Hoje esta meio corrido, desculpe nao poder dar uma atencao melhor.
De uma olhada no que foi sugerido pela Marisiana, a sugestao de usar Left Join no Lugar do Inner Join, ou coisa eh que parte onde dara o resultado vc teria que tirar o menos um( - 1 ) que esta fazendo com que o resultado seja somado no lugar de ser subtraido.
De:
(SUM(TAB083.ntotal * (TAB006.ncomissao)/100) * - 1) ) as resultado
Para:
(SUM(TAB083.ntotal * (TAB006.ncomissao)/100)) ) as resultado
Verifique que o resultado ficara correto pensando no calculo matematico para o resultado, subtracao das comissoes das devolucoes da comissoes de vendas.
Faca os ajustes que a Marisiana sugeriu e vamos ver o que resolve.
Abraco.
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)