sql >> Base de Datos >  >> RDS >> Oracle

Usando 'columna de expresión de caso' en la cláusula where

El motivo de este error es que SQL SELECT las declaraciones son lógicamente * procesado en el siguiente orden:

  • FROM :selección de una tabla o muchas JOINed y todas las combinaciones de filas que coincidan con ON condiciones.

  • WHERE :se evalúan las condiciones y se eliminan las filas que no coinciden.

  • GROUP BY :las filas se agrupan (y cada grupo se contrae en una fila)

  • HAVING :se evalúan las condiciones y se eliminan las filas que no coinciden.

  • SELECT :se evalúa la lista de columnas.

  • DISTINCT :se eliminan las filas duplicadas (si se trata de una instrucción SELECT DISTINCT)

  • UNION , EXCEPT , INTERSECT :la acción de ese operando se realiza sobre las filas de las declaraciones sub-SELECT. Por ejemplo, si se trata de UNION, se recopilan todas las filas (y se eliminan los duplicados, a menos que sea UNION ALL) después de evaluar todas las sentencias sub-SELECT. En consecuencia para los casos EXCEPT o INTERSECT.

  • ORDER BY :las filas están ordenadas.

Por lo tanto, no puede usar en WHERE cláusula, algo que aún no se ha rellenado o calculado. Consulte también esta pregunta:oracle-sql-clause-e Evaluation-order

Tenga en cuenta que los motores de base de datos también pueden elegir otro orden de evaluación para una consulta (¡y eso es lo que suelen hacer!) La única restricción es que los resultados deben ser los mismos que si se hubiera utilizado el orden anterior .

La solución es encerrar la consulta en otra :

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' ;

o para duplicar el cálculo en la condición 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' ;

Supongo que esta es una versión simplificada de su consulta o podría usar:

SELECT ename
     , job
     , 'SALES' AS department
FROM emp
WHERE deptno = 20 ;