CASE .. WHEN在Oracle SQL中的表达式


77

我有1列的表格,并且有以下数据

Status
a1
i
t
a2
a3

我想在我的选择查询中显示以下结果

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

我认为的一种方法是在选择查询中使用Switch When表达式

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

还有什么其他不需要我写的方式?当表达式3次处于Active Status时,可以在一个表达式中检查整个active状态吗?

Answers:


131

您可以使用一个IN子句

就像是

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

看看这个演示

SQL小提琴演示


2
如果可以的话,我建议明确添加ELSE'未知-请致电我们'或其他一些这样的标志。在具有许多用户的大型数据系统中,有时新值会渗入数据中,这有助于敦促用户注意并联系您。我相信没有这个,“ STATUSTEXT”字段将为空白,这将产生较少的用户注释。+1也要向Adriaan进行缩进。
noogrub

Noogrub的好处。我会在此ELSE status之前添加,END如果确实出现新的状态,您将获得基本状态值,而不是的null STATUSTEXT。如果ELSE 'active'其他人引入了新的非活动或终止状态,我不会默认。默认为“活动”是自找麻烦。
杰夫·梅格勒

18

当然...

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

但是,有关此架构的一些令人担忧的事情。首先,如果您有一列含义很深的列,那么在末尾附加一个数字不一定是最好的方法。另外,根据状态数,您可能需要考虑将此列转换为单独表的外键。


根据您的评论,您肯定要将其转换为外键。例如

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)
    )

您的查询将变为

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

这是一个SQL Fiddle演示。


我为我的事业提供了一个一般的例子。但是我对第一个字符不感兴趣。
Nilesh Barai 2012年

+1特别是要提及有关此架构的令人担忧的事情。
Rob van Wijk

17

您可以将其重写为使用ELSE条件 CASE

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

6

使用解码会更容易。

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
尽管此代码段是受欢迎的,并且可以提供一些帮助,但是如果它包含有关如何解决该问题的说明,则将大大改善。否则,您的答案的教育价值就会大大降低-请记住,您将来会为读者回答问题,而不仅仅是现在问的人!请编辑您的答案以添加解释,并指出适用的限制条件和假设
Jean于

1

由于网络搜索Oracle case该链接的顶部,因此我在此处添加了case语句,尽管未回答有关case表达式的问题:

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;

或其他变体:

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;

每个Oracle文档:https : //docs.oracle.com/cd/B10501_01/appdev.920/a96624/04_struc.htm


似乎不支持在的when第二个变体中写倍数case grade when 1,2 then。如果您不知道,请发表评论。
Alexei Martianov,

0

您只能检查状态的第一个字符。为此,您可以使用子字符串功能。

substr(状态,1,1)

就您过去的情况而言。


0

以下语法将起作用:

....
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
请解释这如何回答8年的问题。
Dragonthoughts
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.