簡體   English   中英

在 where 子句中使用“案例表達式列”

[英]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'

這失敗了:

ORA-00904: "%s: 無效標識符"

有沒有辦法克服 Oracle 10.2 SQL 中的這個限制? 如何在 where 子句中使用“案例表達式列”?

出現這個錯誤的原因是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 ;

您的表不包含“部門”列,因此您不能在 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;

這對我有用:

SELECT ename, job
FROM   emp 
WHERE CASE WHEN deptno = 10 THEN 'ACCOUNTS'
           WHEN deptno = 20 THEN 'SALES'
           ELSE 'UNKNOWN'  
      END
      = 'SALES'
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';

Oracle 嘗試通過在 select 之前先執行 where 子句來過濾要從表中掃描的記錄數,這就是您的查詢失敗的原因。 此外,由於過濾器 Department="SALES",您的查詢將永遠不會返回帶有部門的行 - “Accounts or Unknown”

請改用下面的方法,這將很容易被 Engine 獲取:

SELECT ename, job,'SALES' AS department FROM emp WHERE deptno = 20;

嘗試:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM