Ir para conteúdo

POWERED BY:

Arquivado

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

danielsjdr

Consulta meio complicada

Recommended Posts

Boa tarde,A consulta é meio grande e de um sistema aqui da minha empresa. Vou posta ela e depois explico:

select CAMPOLIVRE3, NOMEFANTASIA FANTASIA$,	   (select top 1 CODIGO from TPRDCODIGO(nolock) where IDPRD = D.IDPRD ORDER BY DTCADASTRO DESC) AS CODBARRAS,	   SUM((D2.SALDOFISMAX + D2.SALDFISMIN)/2) AS IDEAL,	   (ROUND((SUM(D1.SALDOFISICO2) - SUM((D2.SALDOFISMAX + D2.SALDFISMIN)/2)),0)*-1) AS FALTA,	   (ROUND((SUM(D1.SALDOFISICO2) - SUM((D2.SALDOFISMAX + D2.SALDFISMIN)/2)),0)*-1)/D3.FATORCONVERSAO,   D.CODUNDCOMPRA, D3.FATORCONVERSAO   from TPRD D(nolock)	  inner join TPRDLOCINFO D2(nolock) on D2.idprd  = D.idprd	  inner join TPRDLOC D1(nolock)	 on D1.codloc = D2.codloc	  inner join TUND D3(nolock)		on D.CODUNDCOMPRA = D3.CODUND   WHERE    (D2.IDPRD = D1.IDPRD) AND (D.IDPRD = D1.IDPRD) AND (D.IDPRD = D2.IDPRD)   AND (CODIGOPRD LIKE '12%')    AND (D1.SALDOFISICO2 < ((D2.SALDOFISMAX + D2.SALDFISMIN)/2))   AND ROUND((D1.SALDOFISICO2 - ((D2.SALDOFISMAX + D2.SALDFISMIN)/2)),0) <> 0      GROUP BY D.IDPRD, D.CAMPOLIVRE3, D.NOMEFANTASIA, D.CODUNDCOMPRA, D3.FATORCONVERSAO   ORDER BY FANTASIA$
Esta consulta está funcionando perfeitamente... Agora o problema é o seguinte, eu gostaria que quando esta conta:
(ROUND((SUM(D1.SALDOFISICO2) - SUM((D2.SALDOFISMAX + D2.SALDFISMIN)/2)),0)*-1)/D3.FATORCONVERSAO
fosse maior que 0 ele exibisse no resultado.Coloque ela então na clausula where da seguinte maneira:
AND ((ROUND((SUM(D1.SALDOFISICO2) - SUM((D2.SALDOFISMAX + D2.SALDFISMIN)/2)),0)*-1)/D3.FATORCONVERSAO)>0
e recebo como resposta:

An aggregate may not appear in the WHERE clause unless it is in a subquery contained in a HAVING clause or a select list, and the column being aggregated is an outer reference.

Alguma ideia?

Compartilhar este post


Link para o post
Compartilhar em outros sites

falai danielsjdr,putz fodah hein, uma vez tava com um lance assim +ou- fudidaço, dai joguei numa table virtual (#tabVirtual) e fiz o filtro na virtual, fica ae a dica, mas se você descobrir posta ae pois é um lance bem interesssantet+

Compartilhar este post


Link para o post
Compartilhar em outros sites

olha.. vamos tentar de 2 formas:

usando having...

select CAMPOLIVRE3, NOMEFANTASIA FANTASIA$,	   (select top 1 CODIGO from TPRDCODIGO(nolock) where IDPRD = D.IDPRD ORDER BY DTCADASTRO DESC) AS CODBARRAS,	   SUM((D2.SALDOFISMAX + D2.SALDFISMIN)/2) AS IDEAL,	   (ROUND((SUM(D1.SALDOFISICO2) - SUM((D2.SALDOFISMAX + D2.SALDFISMIN)/2)),0)*-1) AS FALTA,	   (ROUND((SUM(D1.SALDOFISICO2) - SUM((D2.SALDOFISMAX + D2.SALDFISMIN)/2)),0)*-1)/D3.FATORCONVERSAO,   D.CODUNDCOMPRA, D3.FATORCONVERSAO   from TPRD D(nolock)	  inner join TPRDLOCINFO D2(nolock) on D2.idprd  = D.idprd	  inner join TPRDLOC D1(nolock)	 on D1.codloc = D2.codloc	  inner join TUND D3(nolock)		on D.CODUNDCOMPRA = D3.CODUND   WHERE    (D2.IDPRD = D1.IDPRD) AND (D.IDPRD = D1.IDPRD) AND (D.IDPRD = D2.IDPRD)   AND (CODIGOPRD LIKE '12%')   AND (D1.SALDOFISICO2 < ((D2.SALDOFISMAX + D2.SALDFISMIN)/2))   AND ROUND((D1.SALDOFISICO2 - ((D2.SALDOFISMAX + D2.SALDFISMIN)/2)),0) <> 0      GROUP BY D.IDPRD, D.CAMPOLIVRE3, D.NOMEFANTASIA, D.CODUNDCOMPRA, D3.FATORCONVERSAO   HAVING ((ROUND((SUM(D1.SALDOFISICO2) - SUM((D2.SALDOFISMAX + D2.SALDFISMIN)/2)),0)*-1)/D3.FATORCONVERSAO) > 0   ORDER BY FANTASIA$
ou usando uma view implicita.. que na verdade é uma subquery

SELECT *FROM(select CAMPOLIVRE3, NOMEFANTASIA FANTASIA$,	   (select top 1 CODIGO from TPRDCODIGO(nolock) where IDPRD = D.IDPRD ORDER BY DTCADASTRO DESC) AS CODBARRAS,	   SUM((D2.SALDOFISMAX + D2.SALDFISMIN)/2) AS IDEAL,	   (ROUND((SUM(D1.SALDOFISICO2) - SUM((D2.SALDOFISMAX + D2.SALDFISMIN)/2)),0)*-1) AS FALTA,	   (ROUND((SUM(D1.SALDOFISICO2) - SUM((D2.SALDOFISMAX + D2.SALDFISMIN)/2)),0)*-1)/D3.FATORCONVERSAO AS campo_trava,   D.CODUNDCOMPRA, D3.FATORCONVERSAO   from TPRD D(nolock)	  inner join TPRDLOCINFO D2(nolock) on D2.idprd  = D.idprd	  inner join TPRDLOC D1(nolock)	 on D1.codloc = D2.codloc	  inner join TUND D3(nolock)		on D.CODUNDCOMPRA = D3.CODUND   WHERE    (D2.IDPRD = D1.IDPRD) AND (D.IDPRD = D1.IDPRD) AND (D.IDPRD = D2.IDPRD)   AND (CODIGOPRD LIKE '12%')   AND (D1.SALDOFISICO2 < ((D2.SALDOFISMAX + D2.SALDFISMIN)/2))   AND ROUND((D1.SALDOFISICO2 - ((D2.SALDOFISMAX + D2.SALDFISMIN)/2)),0) <> 0      GROUP BY D.IDPRD, D.CAMPOLIVRE3, D.NOMEFANTASIA, D.CODUNDCOMPRA, D3.FATORCONVERSAO)WHERE campo_trava > 0ORDER BY FANTASIA$

veja se funfa.. ou tenta adaptar a sua realidade de campos, etc.. e posta o resultado para ficar para q tiver duvida de algo parecido, beleza?

;)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Amigo, o metodo citado, do having, é o que melhor vai lhe atender. Ratifico, que deves cuidar mais o relacionamento das tabelas tprd, tprdloc e tprdlocinfo, pois esta usando o inner join, e ao mesmo tempo forçando o relacionamento na clausula where, ou seja, pondo fora a agilidade do join. Se vai comparar na clausula where, faz de uma vez tudo por ali... Tenta, ainda mais nestas subquerys relacionadas, usar a identação certinha, senão, nenhum outro programador vai ler de forma clara seu código. Voltando ao assunto do join e do where, verifica a query abaixo, compara com a sua, e veras, que na sua, fez o inner join com a linha

from TPRD D(nolock)

inner join TPRDLOCINFO D2(nolock) on D2.idprd = D.idprd

e depois refez esta junção, no where, aqui...

(D2.IDPRD = D1.IDPRD) AND (D.IDPRD = D1.IDPRD) AND (D.IDPRD = D2.IDPRD)

Ressalto isto, pois em um tópico da semana passada, já salientei este cuidado a você. As consultas usadas por você hoje estão sendo mais simples, mas se manter o padrão, vai acabar tendo problemas em querys mais complexas, ou mesmo em cubos, perdendo agilidade nestes.

 

Outra coisa que pergunto, um produto vai ter mais do que um código de barras ativo por vez? Se a resposta for, que terá somente 1 ativo, e os antigos serão inativados, daria a sugestão de usar join na tabela tprdcodigo tb, filtrando somente os ativos e relacionando diretamente ao idprd. Sei que o sistema permite criar quantos codigos quizer, deixando todos ativos, mas estuda isto com o cliente, quem sabe melhora a performance da query e evita problemas operacionais dos usuários...

 

Segue a minha sugestão de query, com o uso de having, conforme indicado pelo amigo ska_ska.

 

select

CAMPOLIVRE3,

NOMEFANTASIA FANTASIA$,

(select top 1 CODIGO

from TPRDCODIGO(nolock)

where IDPRD = D.IDPRD

ORDER BY DTCADASTRO DESC) AS CODBARRAS,

SUM((D2.SALDOFISMAX + D2.SALDFISMIN)/2) AS IDEAL,

(ROUND((SUM(D1.SALDOFISICO2) - SUM((D2.SALDOFISMAX + D2.SALDFISMIN)/2)),0)*-1) AS FALTA,

(ROUND((SUM(D1.SALDOFISICO2) - SUM((D2.SALDOFISMAX + D2.SALDFISMIN)/2)),0)*-1)/D3.FATORCONVERSAO,

D.CODUNDCOMPRA,

D3.FATORCONVERSAO

 

from TPRD D(nolock) inner join TPRDLOCINFO D2(nolock) on (D2.idprd = D.idprd)

inner join TPRDLOC D1(nolock) on (D1.IDPRD = D2.IDPRD AND D1.codloc = D2.codloc)

inner join TUND D3(nolock) on (D3.CODUND = D.CODUNDCOMPRA)

 

WHERE (CODIGOPRD LIKE '12%')

AND (D1.SALDOFISICO2 < ((D2.SALDOFISMAX + D2.SALDFISMIN)/2))

AND ROUND((D1.SALDOFISICO2 - ((D2.SALDOFISMAX + D2.SALDFISMIN)/2)),0) <> 0

 

GROUP BY D.IDPRD, D.CAMPOLIVRE3, D.NOMEFANTASIA, D.CODUNDCOMPRA, D3.FATORCONVERSAO

HAVING ((ROUND((SUM(D1.SALDOFISICO2) - SUM((D2.SALDOFISMAX + D2.SALDFISMIN)/2)),0)*-1)/D3.FATORCONVERSAO) > 0

ORDER BY FANTASIA$

 

 

obs.: acho que a identação não vai ficar no topico, mas dah uma tabe nas linhas abaixo da subselect.

Compartilhar este post


Link para o post
Compartilhar em outros sites

ae galera, pode crer esqueci do having, legalzabraçost+

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.