Powodem tego błędu jest to, że SQL SELECT
stwierdzenia są logicznie * przetwarzane w następującej kolejności:
-
FROM
:wybór jednej tabeli lub wielu połączonych i wszystkich kombinacji wierszy, które pasują doON
warunki. -
WHERE
:warunki są oceniane, a niepasujące wiersze są usuwane. -
GROUP BY
:wiersze są pogrupowane (i każda grupa zwija się do jednego wiersza) -
HAVING
:warunki są oceniane, a niepasujące wiersze są usuwane. -
SELECT
:lista kolumn jest oceniana. -
DISTINCT
:zduplikowane wiersze są usuwane (jeśli jest to instrukcja SELECT DISTINCT) -
UNION
,EXCEPT
,INTERSECT
:akcja tego operandu jest wykonywana na wierszach instrukcji sub-SELECT. Na przykład, jeśli jest to UNION, wszystkie wiersze są zbierane (i duplikaty są eliminowane, chyba że jest to UNION ALL) po przeanalizowaniu wszystkich instrukcji podrzędnych SELECT. Odpowiednio dla przypadków EXCEPT lub INTERSECT. -
ORDER BY
:wiersze są uporządkowane.
Dlatego nie możesz używać w WHERE
klauzula, coś, co nie zostało jeszcze wypełnione ani obliczone. Zobacz też to pytanie:oracle-sql-clause-evaluation-order
Zauważ, że silniki baz danych mogą równie dobrze wybrać inną kolejność oceny dla zapytania (i tak zwykle robią!) Jedynym ograniczeniem jest to, że wyniki powinny być takie same, jak w przypadku użycia powyższej kolejności .
Rozwiązaniem jest umieszczanie zapytania w innym :
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' ;
lub duplikować obliczenia w warunku 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' ;
Myślę, że jest to uproszczona wersja Twojego zapytania lub możesz użyć:
SELECT ename
, job
, 'SALES' AS department
FROM emp
WHERE deptno = 20 ;