Array
(
)

AJUDA COMANDO HAVING

João Cristo
   - 08 out 2015

Boa tarde Prezados,
Preciso de uma ajuda com a cláusula HAVING, onde tenho a seguinte consulta abaixo com a necessidade de criar um filtro entre a DATPRO2 e o maior registro do ORDXFUN.DATHORFIM:
SELECT ROUND(SUM(CASE WHEN ORDSERV.STATORD = 'A' THEN 1 ELSE 0 END),2) "ABERTAS/PENDENTES",
ROUND(SUM(CASE WHEN ORDSERV.STATORD = 'F' THEN 1 ELSE 0 END),2) "REALIZADAS/FECHADAS",
ROUND(SUM(CASE WHEN ORDSERV.STATORD = 'C' THEN 1 ELSE 0 END),2) CANCELADAS,
COUNT(*) "GERADAS/SOLICITADAS"

FROM ORDSERV
INNER JOIN TIPMANUT ON TIPMANUT.CODTIPMAN=ORDSERV.CODTIPMAN AND TIPMANUT.CODEMP=ORDSERV.CODEMP_2
INNER JOIN SETEXE ON SETEXE.CODSET=ORDSERV.CODSET AND SETEXE.CODEMP=ORDSERV.CODEMP_4
LEFT OUTER JOIN APLIC ON APLIC.CODAPL=ORDSERV.CODAPL
LEFT OUTER JOIN FUNC ON FUNC.CODFUN=ORDSERV.CODFUN_RESP
LEFT OUTER JOIN PLAMANUT ON ORDSERV.CODPLA=PLAMANUT.CODPLA AND ORDSERV.CODEMP_1=PLAMANUT.CODEMP
LEFT OUTER JOIN FILIAL ON FILIAL.CODFIL=ORDSERV.CODFIL AND FILIAL.CODEMP=ORDSERV.CODEMP_7
LEFT OUTER JOIN LOCAPLIC ON LOCAPLIC.CODLOCAPL=ORDSERV.CODLOCAPL AND LOCAPLIC.CODEMP=ORDSERV.CODEMP
LEFT OUTER JOIN ORDXFUN on ORDXFUN.CODEMP=ORDSERV.CODEMP AND ORDXFUN.CODORD=ORDSERV.CODORD

WHERE (ORDSERV.DATPRO2 between :DATA_INICIAL and :DATA_FINAL) or (MAX(ORDXFUN.DATHORFIM) BETWEEN :Data_Inicial and :Data_Final)
AND ORDSERV.CODEMP=:CODEMP

ORDER BY 1
Resultado:
Dynamic SQL Error
SQL error code = -104
Cannot use an aggregate function in a WHERE clause, use HAVING instead

Marcos P
   - 08 out 2015

Não existe HAVING sem GROUP BY... por isso o erro está sendo gerado, uma vez que o SGBD não está conseguindo tratar o MAX() do WHERE !

Você precisa agrupar seus, para então aplicar o MAX().

João Cristo
   - 08 out 2015

ok e como faria isso nessa consulta

Marcos P
   - 08 out 2015

Comece do básico...

As colunas retornadas no SELECT :

#Código

ROUND(SUM(CASE WHEN ORDSERV.STATORD = 'A' THEN 1 ELSE 0 END),2) "ABERTAS/PENDENTES",
ROUND(SUM(CASE WHEN ORDSERV.STATORD = 'F' THEN 1 ELSE 0 END),2) "REALIZADAS/FECHADAS",
ROUND(SUM(CASE WHEN ORDSERV.STATORD = 'C' THEN 1 ELSE 0 END),2) CANCELADAS,
COUNT(*) "GERADAS/SOLICITADAS"

Já lhe tão uma base de como deve ser montado o GROUP BY.

Depois que o GROUP BY básico estiver funcionando, passe para a implementação do HAVING.

Duas dicas :

1. Nunca use COUNT(*), substitu-a por COUNT(1) ( isso economiza ciclos do pre-compilador da query no SGBD )
2. Sempre que postar código no forum, use a TAG < Inserir Código > ( isso facilita a leitura )

Marcos P
   - 09 out 2015

Conseguiu ?