CASE .. Oracle SQL 中的 WHEN 表达式
Posted
技术标签:
【中文标题】CASE .. Oracle SQL 中的 WHEN 表达式【英文标题】:CASE .. WHEN expression in Oracle SQL 【发布时间】:2012-09-20 23:31:10 【问题描述】:我有 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
有没有其他方法可以做到这一点,我不需要写 When expression 3 times for Active Status 并且可以一次检查整个活动状态单个表达式?
【问题讨论】:
【参考方案1】:您可以使用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 Fiddle DEMO
【讨论】:
如果可以的话,我建议明确添加 ELSE 'UNKNOWN - PLEASE CALL US' 或其他类似的标志。在拥有许多用户的大型数据系统中,有时新值会潜入数据中,这有助于促使用户注意并与您联系。我相信没有这个,“STATUSTEXT”字段将只是空白,这会产生更少的用户 cmets。也为 Adriaan 的漂亮缩进 +1。 noogrub 说的好。我会在END
之前添加ELSE status
,因此如果确实出现了新状态,您将获得基本状态值,而不是STATUSTEXT
的空值。如果其他人引入了新的非活动或终止状态,我不会默认为ELSE 'active'
。默认为“活动”是自找麻烦。【参考方案2】:
当然……
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 来演示。
【讨论】:
我已经为我的事业提供了一个普遍的例子。但是我对第一个字符不感兴趣。 +1 尤其是提到有关此架构的令人担忧的事情。【参考方案3】:您可以重写它以使用 CASE
的 ELSE 条件:
SELECT status,
CASE status
WHEN 'i' THEN 'Inactive'
WHEN 't' THEN 'Terminated'
ELSE 'Active'
END AS StatusText
FROM stage.tst
【讨论】:
【参考方案4】:使用 decode 会更容易。
SELECT
status,
decode ( status, 'a1','Active',
'a2','Active',
'a3','Active',
'i','Inactive',
't','Terminated',
'Default')STATUSTEXT
FROM STATUS
【讨论】:
【参考方案5】:由于Oracle case
的网络搜索位于该链接的顶部,因此我在此处添加案例statement,但未回答有关案例expression 的问题:
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
2nd 变体中写入倍数,例如case grade when 1,2 then
。如果您不知道,请发表评论。【参考方案6】:
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;
【讨论】:
虽然这段代码 sn-p 很受欢迎,并且可能会提供一些帮助,但如果它包含对它如何解决问题的解释,它将大大改进。没有这个,你的回答就没有多少教育价值了——记住你是在为未来的读者回答这个问题,而不仅仅是现在提问的人!请编辑您的答案以添加解释,并说明适用的限制和假设【参考方案7】:您只能检查状态的第一个字符。为此,您使用 substring 函数。
substr(状态, 1,1)
在你过去的情况下。
【讨论】:
【参考方案8】:以下语法可以工作:
....
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
)
【讨论】:
【参考方案9】: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
【讨论】:
请解释一下这是如何回答这个 8 岁的问题的。【参考方案10】:DECODE(SUBSTR(STATUS,1,1),'a','Active','i','Inactive','t','Terminated','N/A')
【讨论】:
以上是关于CASE .. Oracle SQL 中的 WHEN 表达式的主要内容,如果未能解决你的问题,请参考以下文章
如何在oracle sql中的where条件中使用case语句?
如何从oracle sql中的选择计数中对rownum使用case语句?