Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Usando 'coluna de expressão case' na cláusula where


A razão para este erro é que SQL SELECT declarações são logicamente * processados ​​na seguinte ordem:

  • FROM :seleção de uma ou várias tabelas JOINed e todas as combinações de linhas que correspondem ao ON condições.

  • WHERE :as condições são avaliadas e as linhas que não correspondem são removidas.

  • GROUP BY :as linhas são agrupadas (e cada grupo é reduzido a uma linha)

  • HAVING :as condições são avaliadas e as linhas que não correspondem são removidas.

  • SELECT :a lista de colunas é avaliada.

  • DISTINCT :linhas duplicadas são removidas (se for uma instrução SELECT DISTINCT)

  • UNION , EXCEPT , INTERSECT :a ação desse operando é executada nas linhas de instruções sub-SELECT. Por exemplo, se for um UNION, todas as linhas serão reunidas (e as duplicatas eliminadas, a menos que seja um UNION ALL) depois que todas as instruções sub-SELECT forem avaliadas. De acordo com os casos EXCEPT ou INTERSECT.

  • ORDER BY :as linhas são ordenadas.

Portanto, você não pode usar em WHERE cláusula, algo que ainda não foi preenchido ou calculado. Veja também esta pergunta:oracle-sql-clause-evaluation-order

Observe que os mecanismos de banco de dados também podem escolher outra ordem de avaliação para uma consulta (e é isso que eles costumam fazer!) A única restrição é que os resultados devem ser os mesmos que se a ordem acima fosse usada forte> .

A solução é colocar a consulta em outra :
SELECT *
FROM
  ( SELECT ename
         , job
         , CASE deptno
             WHEN 10 THEN 'ACCOUNTS'
             WHEN 20 THEN 'SALES'
                     ELSE 'UNKNOWN'
           END AS department
    FROM emp
  ) tmp
WHERE department = 'SALES' ;

ou para duplicar o cálculo na condição WHERE :
SELECT ename
     , job
     , CASE deptno
         WHEN 10 THEN 'ACCOUNTS'
         WHEN 20 THEN 'SALES'
                 ELSE 'UNKNOWN'
       END AS department
FROM emp
WHERE
    CASE deptno
      WHEN 10 THEN 'ACCOUNTS'
      WHEN 20 THEN 'SALES'
              ELSE 'UNKNOWN'
    END = 'SALES' ;

Acho que esta é uma versão simplificada da sua consulta ou você pode usar:
SELECT ename
     , job
     , 'SALES' AS department
FROM emp
WHERE deptno = 20 ;