CASE .. WHEN Ausdruck in Oracle SQL


78

Ich habe die Tabelle mit 1 Spalte und hat folgende Daten

Status
a1
i
t
a2
a3

Ich möchte das folgende Ergebnis in meiner Auswahlabfrage anzeigen

Status| STATUSTEXT
a1    | Active
i     | Inactive
t     | Terminated
a2    | Active
a3    | Active

Eine Möglichkeit, die ich mir vorstellen könnte, war die Verwendung eines Switch When-Ausdrucks in einer ausgewählten Abfrage

SELECT
status,
CASE status 
WHEN 'a1' THEN 'Active'
WHEN 'a2' THEN 'Active'
WHEN 'a3' THEN 'Active'
WHEN 'i' THEN 'Inactive'
WHEN 't' THEN 'Terminated'
END AS StatusText
FROM stage.tst

Gibt es eine andere Möglichkeit, dies zu tun, wenn ich nicht schreiben muss, wenn der Ausdruck dreimal für den aktiven Status und der gesamte aktive Status in einem einzigen Ausdruck überprüft werden können?

Antworten:


132

Sie könnten eine INKlausel verwenden

Etwas wie

SELECT
  status,
  CASE
    WHEN STATUS IN('a1','a2','a3')
    THEN 'Active'
    WHEN STATUS = 'i'
    THEN 'Inactive'
    WHEN STATUS = 't'
    THEN 'Terminated'
  END AS STATUSTEXT
FROM
  STATUS

Schauen Sie sich diese Demo an

SQL Fiddle DEMO


2
Wenn ich darf, schlage ich vor, ELSE 'UNBEKANNT - BITTE RUFEN SIE UNS' oder ein anderes solches Flag explizit an. In größeren Datensystemen mit vielen Benutzern schleichen sich manchmal neue Werte in die Daten ein, und es kann hilfreich sein, Benutzer zu drängen, Sie zu bemerken und zu kontaktieren. Ich glaube, ohne dies wird das Feld "STATUSTEXT" nur leer sein, was weniger Benutzerkommentare erzeugt. +1 an Adriaan für den schönen Einzug.
Noogrub

Guter Punkt von Noogrub. Ich würde ELSE statusvorher hinzufügen END, wenn sich ein neuer Status einschleicht, erhalten Sie den Basisstatuswert anstelle einer Null für STATUSTEXT. Ich würde nicht standardmäßig, ELSE 'active'falls ein neuer inaktiver oder gekündigter Status von anderen eingeführt wird. Die Standardeinstellung "Aktiv" ist problematisch.
Jeff Mergler

18

Na sicher...

select case substr(status,1,1) -- you're only interested in the first character.
            when 'a' then 'Active'
            when 'i' then 'Inactive'
            when 't' then 'Terminated'
       end as statustext
  from stage.tst

Es gibt jedoch einige besorgniserregende Dinge an diesem Schema. Erstens, wenn Sie eine Spalte haben, die etwas bedeutet, und eine Zahl am Ende anhängen, ist dies nicht unbedingt der beste Weg. Abhängig von der Anzahl der Status, die Sie haben, sollten Sie diese Spalte möglicherweise in einen Fremdschlüssel für eine separate Tabelle umwandeln.


Basierend auf Ihrem Kommentar möchten Sie dies definitiv in einen Fremdschlüssel verwandeln. Zum Beispiel

create table statuses ( -- Not a good table name :-)
    status varchar2(10)
  , description varchar2(10)
  , constraint pk_statuses primary key (status)
    )

create table tst (
    id number
  , status varchar2(10)
  , constraint pk_tst primary key (id)
  , constraint fk_tst foreign key (status) references statuses (status)
    )

Ihre Anfrage wird dann

select a.status, b.description
  from tst a
  left outer join statuses b
    on a.status = b.status

Hier ist eine SQL-Geige zur Demonstration.


Ich habe ein allgemeines Beispiel für meine Sache geliefert. Ich interessiere mich jedoch nicht nur für den ersten Charakter.
Nilesh Barai

+1, besonders um die besorgniserregenden Dinge an diesem Schema zu erwähnen.
Rob van Wijk

17

Sie können es umschreiben, um die ELSE-Bedingung von a zu verwenden CASE:

SELECT status,
       CASE status
         WHEN 'i' THEN 'Inactive'
         WHEN 't' THEN 'Terminated'
         ELSE 'Active'
       END AS StatusText
FROM   stage.tst 

6

Die Dekodierung ist einfacher .

SELECT
  status,
    decode ( status, 'a1','Active',
                     'a2','Active',
                     'a3','Active',
                     'i','Inactive',
                     't','Terminated',
                     'Default')STATUSTEXT
FROM STATUS

1
SELECT
  STATUS,
  CASE
    WHEN STATUS IN('a1','a2','a3') 
     THEN 'Active'
    WHEN STATUS = 'i' 
     THEN 'Inactive'
    WHEN STATUS = 't'
     THEN 'Terminated'  ELSE null
  END AS STATUSTEXT
FROM
  stage.tst;

1
Obwohl dieses Code-Snippet willkommen ist und möglicherweise Hilfe bietet, wäre es erheblich verbessert, wenn es eine Erklärung zur Behandlung der Frage enthalten würde. Ohne das hat Ihre Antwort einen viel geringeren pädagogischen Wert - denken Sie daran, dass Sie die Frage in Zukunft für die Leser beantworten, nicht nur für die Person, die jetzt fragt! Bearbeiten Sie Ihre Antwort Erklärung hinzuzufügen, und geben einen Hinweis darauf, was Einschränkungen und Annahmen gelten
jean

1

Da die Websuche nach Oracle caseSpitzen zu diesem Link sucht , füge ich hier eine Fallerklärung hinzu , beantworte jedoch nicht die Frage nach dem Fallausdruck :

CASE
   WHEN grade = 'A' THEN dbms_output.put_line('Excellent');
   WHEN grade = 'B' THEN dbms_output.put_line('Very Good');
   WHEN grade = 'C' THEN dbms_output.put_line('Good');
   WHEN grade = 'D' THEN dbms_output.put_line('Fair');
   WHEN grade = 'F' THEN dbms_output.put_line('Poor');
   ELSE dbms_output.put_line('No such grade');
END CASE;

oder eine andere Variante:

CASE grade
   WHEN 'A' THEN dbms_output.put_line('Excellent');
   WHEN 'B' THEN dbms_output.put_line('Very Good');
   WHEN 'C' THEN dbms_output.put_line('Good');
   WHEN 'D' THEN dbms_output.put_line('Fair');
   WHEN 'F' THEN dbms_output.put_line('Poor');
   ELSE dbms_output.put_line('No such grade');
END CASE;

Gemäß Oracle-Dokumenten: https://docs.oracle.com/cd/B10501_01/appdev.920/a96624/04_struc.htm


scheint nicht unterstützt zu werden, um Vielfache in when2. Variante wie zu schreiben case grade when 1,2 then. Wenn Sie etwas anderes wissen, kommentieren Sie bitte.
Alexei Martianov

0

Sie können nur das erste Zeichen des Status überprüfen. Hierfür verwenden Sie die Teilzeichenfolgenfunktion.

substr (Status, 1,1)

In deinem Fall vorbei.


0

Folgende Syntax würde funktionieren:

....
where x.p_NBR =to_number(substr(y.k_str,11,5))
and x.q_nbr = 
 (case 
 when instr(substr(y.m_str,11,9),'_') = 6   then  to_number(substr(y.m_str,11,5))
 when instr(substr(y.m_str,11,9),'_') = 0   then  to_number(substr(y.m_str,11,9))
  else 
       1
  end
)

0
CASE TO_CHAR(META.RHCONTRATOSFOLHA.CONTRATO)
WHEN '91' AND TO_CHAR(META.RHCONTRATOSFOLHA.UNIDADE) = '0001' THEN '91RJ'
WHEN '91' AND TO_CHAR(META.RHCONTRATOSFOLHA.UNIDADE) = '0002' THEN '91SP'
END CONTRATO,

00905. 00000 -  "missing keyword"
*Cause:    
*Action:
Erro na linha: 15 Coluna: 11

2
Bitte erläutern Sie, wie dies die 8 Jahre alte Frage beantwortet.
Dragon Thoughts
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.