it-swarm.com.de

Verwendung der Spalte "Fallausdruck" in where-Klausel

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

Das schlägt fehl:

ORA-00904: "% s: ungültige Kennung" 

Gibt es eine Möglichkeit, diese Einschränkung in Oracle 10.2 SQL zu überwinden?.

21
EugeneP

Der Grund für diesen Fehler ist, dass SQL-Anweisungen SELECT logisch * in der folgenden Reihenfolge verarbeitet werden:

  • FROM: Auswahl einer oder mehrerer JOIN-Tabellen und aller Zeilenkombinationen, die den Bedingungen ON entsprechen.

  • WHERE: Bedingungen werden ausgewertet und nicht übereinstimmende Zeilen werden entfernt.

  • GROUP BY: Zeilen werden gruppiert (und jede Gruppe wird zu einer Zeile zusammengefasst)

  • HAVING: Bedingungen werden ausgewertet und nicht übereinstimmende Zeilen werden entfernt.

  • SELECT: Liste der Spalten wird ausgewertet.

  • DISTINCT: doppelte Zeilen werden entfernt (falls es sich um eine SELECT DISTINCT-Anweisung handelt)

  • UNION, EXCEPT, INTERSECT: Die Aktion dieses Operanden wird für die Zeilen der untergeordneten SELECT-Anweisungen ausgeführt. Wenn es sich beispielsweise um eine UNION handelt, werden alle Zeilen erfasst (und Duplikate entfernt, sofern es sich nicht um eine UNION ALL handelt), nachdem alle untergeordneten SELECT-Anweisungen ausgewertet wurden. Entsprechend für die EXCEPT- oder INTERSECT-Fälle.

  • ORDER BY: Zeilen werden sortiert.

Daher können Sie in der WHERE-Klausel nichts verwenden, was noch nicht ausgefüllt oder berechnet wurde. Siehe auch diese Frage: Oracle-SQL-Klausel-Evaluierungsreihenfolge

* logisch verarbeitet:  Beachten Sie, dass Datenbank-Engines auch eine andere Auswertungsreihenfolge für eine Abfrage wählen können (und das tun sie normalerweise!). Die einzige Einschränkung ist, dass die Ergebnisse die sein sollten das gleiche, als ob die obige Reihenfolge verwendet wurde .


Lösung ist , die Abfrage in eine andere einzufügen :

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

oder um die Berechnung in der WHERE-Bedingung zu duplizieren :

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

Ich denke, dies ist eine vereinfachte Version Ihrer Abfrage, oder Sie könnten Folgendes verwenden:

_SELECT ename
     , job
     , 'SALES' AS department
FROM emp
WHERE deptno = 20 ;
_
41
ypercubeᵀᴹ

Ihre Tabelle enthält keine Spalte "Abteilung" und kann daher nicht in Ihrer where-Klausel referenziert werden. Verwenden Sie stattdessen deptno.

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

Diese Arbeit für mich:

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

versuchen:

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

Oracle versucht, die Anzahl der zu durchsuchenden Datensätze aus der Tabelle zu filtern, indem Sie zuerst die where-Klausel auswählen, bevor Sie select auswählen. Deshalb schlägt Ihre Abfrage fehl. Darüber hinaus hätte Ihre Abfrage aufgrund des Filters Department = "SALES" niemals Zeilen mit der Abteilung "Konten oder Unbekannt" zurückgegeben.

Versuchen Sie es stattdessen unten, das kann einfach von Engine abgerufen werden:

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

0
Himansh Gautam