Причина этой ошибки заключается в том, что операторы SQL SELECT
логически * обрабатываются в следующем порядке:
FROM
: выбор одной таблицы или нескольких объединенных и всех комбинаций строк, соответствующих условиям 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 -valuation-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 ;