sql >> Database teknologi >  >> RDS >> Oracle

Brug af 'case-udtrykskolonne' i where-sætning

Årsagen til denne fejl er, at SQL SELECT udsagn er logisk * behandles i følgende rækkefølge:

  • FROM :valg af en tabel eller mange JOIN-tabeller og alle rækkekombinationer, der matcher ON betingelser.

  • WHERE :betingelser evalueres, og rækker, der ikke matcher, fjernes.

  • GROUP BY :rækker grupperes (og hver gruppe skjules til én række)

  • HAVING :betingelser evalueres, og rækker, der ikke matcher, fjernes.

  • SELECT :listen over kolonner evalueres.

  • DISTINCT :duplikerede rækker fjernes (hvis det er en SELECT DISTINCT-sætning)

  • UNION , EXCEPT , INTERSECT :handlingen af ​​den operand udføres på rækkerne af sub-SELECT-sætninger. For eksempel, hvis det er en UNION, samles alle rækker (og dubletter elimineres, medmindre det er en UNION ALL), efter at alle sub-SELECT-sætninger er evalueret. I overensstemmelse hermed for EXCEPT eller INTERSECT tilfældene.

  • ORDER BY :rækker er ordnet.

Derfor kan du ikke bruge i WHERE klausul, noget der ikke er blevet udfyldt eller beregnet endnu. Se også dette spørgsmål:oracle-sql-clause-evaluation-order

Bemærk, at databasemotorer lige så godt kan vælge en anden evalueringsrækkefølge for en forespørgsel (og det gør de normalt!) Den eneste begrænsning er, at resultaterne skal være de samme, som hvis ovenstående rækkefølge blev brugt stærk> .

Løsningen er at indeslutte forespørgslen i en anden :

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

eller for at duplikere beregningen i WHERE-tilstanden :

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

Jeg gætter på, at dette er en forenklet version af din forespørgsel, eller du kan bruge:

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


  1. INSERT-sætningen er i konflikt med FOREIGN KEY-begrænsningen - SQL Server

  2. Sideinddeling med OFFSET / FETCH:En bedre måde

  3. Er der en automatisk ændringstidsstempeltype for Oracle-kolonner?

  4. Bedste måde at implementere et revisionsspor i SQL Server?