Подтвердить что ты не робот

Использование столбца выражения case в where where

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? Как использовать столбец "case case" в разделе where?

4b9b3361

Ответ 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 ;

Ответ 2

В вашей таблице нет столбца "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;

Ответ 3

Эта работа для меня:

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

Ответ 4

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

Ответ 5

попробовать:

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

Ответ 6

Oracle пытается отфильтровать количество записей, которые нужно отсканировать из таблицы, перейдя к предложению where перед тем, как выбрать, поэтому ваш запрос завершается с ошибкой. Более того, ваш запрос никогда бы не возвращал строки с отделением - "Учетные записи или неизвестные" из-за фильтра Department = "SALES"

Попробуйте ниже, это будет легко получить с помощью Engine:

SELECT ename, job, отдел "ПРОДАЖИ" FROM emp WHERE deptno = 20;