在where子句中使用'case expression column'

时间:2011-07-01 08:50:45

标签: sql oracle oracle10g ora-00904

SELECT ename
  ,    job
  ,    CASE deptno
         WHEN 10
           THEN 'ACCOUNTS'
         WHEN 20
           THEN 'SALES'
         ELSE 'UNKNOWN'
       END AS department
FROM emp /* !!! */ 
WHERE department = 'SALES'

这失败了:

  

ORA-00904:“%s:无效标识符”

有没有办法克服Oracle 10.2 SQL中的这个限制? 如何在where子句中使用'case expression column'?

6 个答案:

答案 0 :(得分:40)

此错误的原因是SQL SELECT语句 逻辑 * 按以下顺序处理:

  • FROM :选择一个或多个JOINed以及符合ON条件的所有行组合。

  • WHERE :评估条件并删除不匹配的行。

  • GROUP BY :对行进行分组(每个组都折叠为一行)

  • HAVING :评估条件并删除不匹配的行。

  • SELECT :评估列列表。

  • DISTINCT :删除重复的行(如果是SELECT DISTINCT语句)

  • UNION EXCEPT INTERSECT :该操作数的操作取决于子SELECT语句的行。例如,如果它是UNION,则在评估所有子SELECT语句之后,将收集所有行(并删除重复项,除非它是UNION ALL)。因此对于EXCEPT或INTERSECT案件。

  • 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 ;

答案 1 :(得分:7)

您的表格不包含“department”列,因此您无法在where子句中引用它。请改用deptno。

SELECT ename
,      job
,      CASE deptno
          WHEN 10
          THEN 'ACCOUNTS'
          WHEN 20
          THEN 'SALES'
          ELSE 'UNKNOWN'
       END AS department
FROM   emp /* !!! */ where deptno = 20;

答案 2 :(得分:4)

这项工作对我来说:

SELECT ename, job
FROM   emp 
WHERE CASE WHEN deptno = 10 THEN 'ACCOUNTS'
           WHEN deptno = 20 THEN 'SALES'
           ELSE 'UNKNOWN'  
      END
      = 'SALES'

答案 3 :(得分:1)

select emp_.*
from (SELECT ename
  ,    job
  ,    CASE deptno
         WHEN 10
           THEN 'ACCOUNTS'
         WHEN 20
           THEN 'SALES'
         ELSE 'UNKNOWN'
       END AS department
FROM emp /* !!! */ ) emp_ where emp_.department='UNKNOWN';

答案 4 :(得分:0)

尝试:

  SQL> SELECT ename
      2  ,      job
      3  ,      CASE
      4            WHEN  deptno = 10
      5            THEN 'ACCOUNTS'
      6            WHEN  deptno = 20
      7            THEN 'SALES'
     12            ELSE 'UNKNOWN'
     13         END AS department
     14  FROM   emp /* !!! */ where department = 'SALES';

答案 5 :(得分:0)

Oracle尝试通过先选择where子句来筛选要从表中扫描的记录数,然后再选择这是查询失败的原因。此外,您的查询将永远不会返回包含部门的行 - "帐户或未知"因为过滤部门=" SALES"

请尝试以下方法,以便引擎轻松获取:

SELECT ename,job,' SALES' AS部门 来自emp 在哪里deptno = 20;