出现这个错误的原因是SQLSELECT
语句在逻辑上*按如下顺序处理:
FROM
: 选择一个表或多个 JOINed 表以及匹配ON
条件的所有行组合。
WHERE
: 评估条件并删除不匹配的行。
GROUP BY
: 行被分组(每个组折叠成一行)
HAVING
: 评估条件并删除不匹配的行。
SELECT
:评估列列表。
DISTINCT
: 删除重复行(如果是 SELECT DISTINCT 语句)
UNION
, EXCEPT
, INTERSECT
: 该操作数的操作是在子 SELECT 语句的行上执行的。例如,如果它是 UNION,则在评估所有子 SELECT 语句后,将收集所有行(并消除重复项,除非它是 UNION ALL)。因此,对于 EXCEPT 或 INTERSECT 情况。
ORDER BY
: 行是有序的。
因此,您不能使用 inWHERE
子句,即尚未填充或计算的内容。另请参阅此问题: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 ;