sql >> Database >  >> RDS >> Oracle

Het gebruik van 'case expression column' in where-clausule

De reden voor deze fout is dat SQL SELECT uitspraken zijn logisch * verwerkt in de volgende volgorde:

  • FROM :selectie van één tabel of veel JOINed en alle rijencombinaties die overeenkomen met de ON voorwaarden.

  • WHERE :voorwaarden worden geëvalueerd en rijen die niet overeenkomen, worden verwijderd.

  • GROUP BY :rijen zijn gegroepeerd (en elke groep wordt samengevouwen tot één rij)

  • HAVING :voorwaarden worden geëvalueerd en rijen die niet overeenkomen, worden verwijderd.

  • SELECT :lijst met kolommen wordt geëvalueerd.

  • DISTINCT :dubbele rijen worden verwijderd (als het een SELECT DISTINCT-instructie is)

  • UNION , EXCEPT , INTERSECT :de actie van die operand wordt uitgevoerd op de rijen met sub-SELECT-instructies. Als het bijvoorbeeld een UNION is, worden alle rijen verzameld (en duplicaten verwijderd tenzij het een UNION ALL is) nadat alle sub-SELECT-instructies zijn geëvalueerd. Dienovereenkomstig voor de BEHALVE of INTERSECT-gevallen.

  • ORDER BY :rijen zijn geordend.

Daarom kunt u niet gebruiken in WHERE clausule, iets dat nog niet is ingevuld of berekend. Zie ook deze vraag:oracle-sql-clause-evaluation-order

Merk op dat database-engines net zo goed een andere evaluatievolgorde voor een zoekopdracht kunnen kiezen (en dat is wat ze meestal doen!) De enige beperking is dat de resultaten hetzelfde moeten zijn alsof de bovenstaande volgorde was gebruikt sterk> .

Oplossing is om de vraag in een andere in te sluiten :

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

of om de berekening te dupliceren in de WHERE-voorwaarde :

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

Ik denk dat dit een vereenvoudigde versie van uw vraag is of dat u het volgende zou kunnen gebruiken:

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


  1. Hoe krijg ik ForeignCollection Field in Cursor in Ormlite

  2. Hoe lijst buitenlandse sleutels op te sommen

  3. PostgreSQL-query om per dag te tellen/groeperen en dagen zonder gegevens weer te geven

  4. Gegevens ophalen uit opgeslagen procedure met meerdere resultaatsets