Oracle
 sql >> Database >  >> RDS >> Oracle

Utilizzo della "colonna delle espressioni case" nella clausola where

Il motivo di questo errore è che SQL SELECT le affermazioni sono logicamente * elaborati nel seguente ordine:

  • FROM :selezione di una o più tabelle JOINed e tutte le combinazioni di righe che corrispondono a ON condizioni.

  • WHERE :le condizioni vengono valutate e le righe che non corrispondono vengono rimosse.

  • GROUP BY :le righe sono raggruppate (e ogni gruppo viene compresso in una riga)

  • HAVING :le condizioni vengono valutate e le righe che non corrispondono vengono rimosse.

  • SELECT :viene valutato l'elenco delle colonne.

  • DISTINCT :le righe duplicate vengono rimosse (se si tratta di un'istruzione SELECT DISTINCT)

  • UNION , EXCEPT , INTERSECT :l'azione di quell'operando viene eseguita sulle righe delle istruzioni sub-SELECT. Ad esempio, se si tratta di UNION, tutte le righe vengono raccolte (e i duplicati eliminati a meno che non sia UNION ALL) dopo che tutte le istruzioni sub-SELECT sono state valutate. Di conseguenza per i casi EXCEPT o INTERSECT.

  • ORDER BY :le righe sono ordinate.

Pertanto, non puoi utilizzare in WHERE clausola, qualcosa che non è stato ancora compilato o calcolato. Vedi anche questa domanda:oracle-sql-clause-evaluation-order

Nota che i motori di database possono anche scegliere un altro ordine di valutazione per una query (ed è quello che fanno di solito!). L'unica restrizione è che i risultati dovrebbero essere gli stessi come se fosse stato utilizzato l'ordine sopra .

La soluzione è racchiudere la query in un'altra :

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 per duplicare il calcolo nella condizione 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' ;

Immagino che questa sia una versione semplificata della tua query o potresti usare:

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