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