Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using 'case expression column' in where clause

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

This fails:

ORA-00904: "%s: invalid identifier"

Is there a way to overcome this limitation in Oracle 10.2 SQL ? How to use the 'case expression column' in where clause ?

like image 482
EugeneP Avatar asked Jul 01 '11 08:07

EugeneP


People also ask

Can I use a CASE statement in a WHERE clause?

CASE can be used in any statement or clause that allows a valid expression. For example, you can use CASE in statements such as SELECT, UPDATE, DELETE and SET, and in clauses such as select_list, IN, WHERE, ORDER BY, and HAVING.

Can we write CASE statement in WHERE clause in SQL Server?

The case statement in SQL returns a value on a specified condition. We can use a Case statement in select queries along with Where, Order By, and Group By clause. It can be used in the Insert statement as well.

Can CASE statement be used in WHERE clause Oracle?

Introduction to Oracle CASE expression You can use a CASE expression in any statement or clause that accepts a valid expression. For example, you can use the CASE expression in statements such as SELECT , UPDATE , or DELETE , and in clauses like SELECT , WHERE , HAVING , and ORDDER BY .

Which expression can be used in a WHERE clause?

Any legal arithmetic expression involving columns, constants, functions and arithmetic operators (+, -, * and /) is permitted in a WHERE clause. Parentheses may be used as necessary to define evaluation order.


1 Answers

The reason for this error is that SQL SELECT statements are logically * processed in the following order:

  • FROM: selection of one table or many JOINed ones and all rows combinations that match the ON conditions.

  • WHERE: conditions are evaluated and rows that do not match are removed.

  • GROUP BY: rows are grouped (and every group collapses to one row)

  • HAVING: conditions are evaluated and rows that do not match are removed.

  • SELECT: list of columns is evaluated.

  • DISTINCT: duplicate rows are removed (if it's a SELECT DISTINCT statement)

  • UNION, EXCEPT, INTERSECT: the action of that operand is taken upon the rows of sub-SELECT statements. For example, if it's a UNION, all rows are gathered (and duplicates eliminated unless it's a UNION ALL) after all sub-SELECT statements are evaluated. Accordingly for the EXCEPT or INTERSECT cases.

  • ORDER BY: rows are ordered.

Therefore, you can't use in WHERE clause, something that hasn't been populated or calculated yet. See also this question: oracle-sql-clause-evaluation-order

* logically processed:Note that database engines may as well choose another order of evaluation for a query (and that's what they usually do!) The only restriction is that the results should be the same as if the above order was used.


Solution is to enclose the query in another one:

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

or to duplicate the calculation in the WHERE condition:

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

I guess this is a simplified version of your query or you could use:

SELECT ename      , job      , 'SALES' AS department FROM emp WHERE deptno = 20 ; 
like image 169
ypercubeᵀᴹ Avatar answered Sep 21 '22 13:09

ypercubeᵀᴹ