Årsagen til denne fejl er, at SQL SELECT
udsagn er logisk * behandles i følgende rækkefølge:
-
FROM
:valg af en tabel eller mange JOIN-tabeller og alle rækkekombinationer, der matcherON
betingelser. -
WHERE
:betingelser evalueres, og rækker, der ikke matcher, fjernes. -
GROUP BY
:rækker grupperes (og hver gruppe skjules til én række) -
HAVING
:betingelser evalueres, og rækker, der ikke matcher, fjernes. -
SELECT
:listen over kolonner evalueres. -
DISTINCT
:duplikerede rækker fjernes (hvis det er en SELECT DISTINCT-sætning) -
UNION
,EXCEPT
,INTERSECT
:handlingen af den operand udføres på rækkerne af sub-SELECT-sætninger. For eksempel, hvis det er en UNION, samles alle rækker (og dubletter elimineres, medmindre det er en UNION ALL), efter at alle sub-SELECT-sætninger er evalueret. I overensstemmelse hermed for EXCEPT eller INTERSECT tilfældene. -
ORDER BY
:rækker er ordnet.
Derfor kan du ikke bruge i WHERE
klausul, noget der ikke er blevet udfyldt eller beregnet endnu. Se også dette spørgsmål:oracle-sql-clause-evaluation-order
Bemærk, at databasemotorer lige så godt kan vælge en anden evalueringsrækkefølge for en forespørgsel (og det gør de normalt!) Den eneste begrænsning er, at resultaterne skal være de samme, som hvis ovenstående rækkefølge blev brugt stærk> .
Løsningen er at indeslutte forespørgslen i en anden :
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' ;
eller for at duplikere beregningen i WHERE-tilstanden :
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' ;
Jeg gætter på, at dette er en forenklet version af din forespørgsel, eller du kan bruge:
SELECT ename
, job
, 'SALES' AS department
FROM emp
WHERE deptno = 20 ;