Ответ 1
Причиной этой ошибки является то, что операторы SQL SELECT
обрабатываются логически * в следующем порядке:
-
FROM
: выбор одной таблицы или множества JOINed и всех комбинаций строк, соответствующих условиямON
. -
WHERE
: условия оцениваются, а строки, которые не совпадают, удаляются. -
GROUP BY
: строки сгруппированы (и каждая группа сворачивается в одну строку) -
HAVING
: условия оцениваются, а строки, которые не совпадают, удаляются. -
SELECT
: оценивается список столбцов. -
DISTINCT
: удаляются повторяющиеся строки (если это оператор SELECT DISTINCT) -
UNION
,EXCEPT
,INTERSECT
: действие этого операнда выполняется по строкам sub-SELECT. Например, если это UNION, все строки собираются (и дубликаты исключаются, если только они не являются UNION ALL) после того, как все вычисления SUB SELECT оцениваются. Соответственно для случаев ИСКЛЮЧЕНИЯ или ИНТЕРЕСА. -
ORDER BY
: упорядочены строки.
Следовательно, вы не можете использовать в предложении WHERE
то, что еще не было заполнено или подсчитано. См. Также этот вопрос: oracle-sql-clause-evaluation-order
* логически обработано: Обратите внимание, что двигатели базы данных могут также выбрать другой порядок оценки для запроса (и то, что они обычно делают!) Единственное ограничение заключается в том, что результаты должны быть такими же, как если бы использовался вышеприведенный порядок.
Решение заключить запрос в другой:
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' ;
или дублировать вычисление в условии 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' ;
Я предполагаю, что это упрощенная версия вашего запроса, или вы можете использовать:
SELECT ename
, job
, 'SALES' AS department
FROM emp
WHERE deptno = 20 ;