Oracle
 sql >> Base de données >  >> RDS >> Oracle

Utilisation de la 'colonne d'expression de cas' dans la clause where

La raison de cette erreur est que SQL SELECT les déclarations sont logiquement * traitées dans l'ordre suivant :

  • FROM  :sélection d'une table ou de plusieurs tables jointes et de toutes les combinaisons de lignes qui correspondent au ON conditions.

  • WHERE  :les conditions sont évaluées et les lignes qui ne correspondent pas sont supprimées.

  • GROUP BY  :les lignes sont regroupées (et chaque groupe se réduit à une seule ligne)

  • HAVING  :les conditions sont évaluées et les lignes qui ne correspondent pas sont supprimées.

  • SELECT :la liste des colonnes est évaluée.

  • DISTINCT :les lignes en double sont supprimées (s'il s'agit d'une instruction SELECT DISTINCT)

  • UNION , EXCEPT , INTERSECT :l'action de cet opérande est prise sur les lignes des sous-instructions SELECT. Par exemple, s'il s'agit d'un UNION, toutes les lignes sont rassemblées (et les doublons éliminés sauf s'il s'agit d'un UNION ALL) après l'évaluation de toutes les instructions sous-SELECT. Par conséquent pour les cas EXCEPT ou INTERSECT.

  • ORDER BY :les lignes sont ordonnées.

Par conséquent, vous ne pouvez pas utiliser dans WHERE clause, quelque chose qui n'a pas encore été rempli ou calculé. Voir aussi cette question :oracle-sql-clause-evaluation-order

Notez que les moteurs de base de données peuvent également choisir un autre ordre d'évaluation pour une requête (et c'est ce qu'ils font habituellement !) La seule restriction est que les résultats doivent être les mêmes que si l'ordre ci-dessus était utilisé .

La solution consiste à enfermer la requête dans une autre :

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 pour dupliquer le calcul dans la condition 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' ;

Je suppose qu'il s'agit d'une version simplifiée de votre requête ou que vous pourriez utiliser :

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