CASE 语句将 NUMBER 转换为 CHAR,但在 Oracle SQL 中保留原始 NUMBER 的 ELSE
Posted
技术标签:
【中文标题】CASE 语句将 NUMBER 转换为 CHAR,但在 Oracle SQL 中保留原始 NUMBER 的 ELSE【英文标题】:CASE statement turning a NUMBER into a CHAR, but the ELSE to keep original NUMBER in Oracle SQL 【发布时间】:2015-01-02 01:08:59 【问题描述】:我正在尝试创建一个简单的查询,它将当前包含值 0、1、2、3、4、5 的评分/评估列转换为 Terrible、Poor、Bad、Mediocre 和 Good。但正如您所见,标签值只有 5 个,而数字值只有 6 个。
所以数字 5 需要显示为 5,而所有其他数字将变成它们各自的标签(可怕、差等)。
我目前的查询如下:
SELECT course_id,
student_id,
CASE eval
WHEN 0 THEN 'Terrible'
WHEN 1 THEN 'Bad'
WHEN 2 THEN 'Mediocre'
WHEN 3 THEN 'Fair'
WHEN 4 THEN 'Good'
END
FROM booking;
在以下查询结果中,我知道标记为10121
的COURSE_ID
的评估值为5
所有其他的都是空的,所以它们是空白的很好。但是10121
需要显示为5
。
如果我尝试应用ELSE
语句来返回原始值(通过执行inner select
语句),它会显示ERROR at line 9: ORA-00932: inconsistent datatypes: expected CHAR got NUMBER
COURSE_ID STUDENT_ID CASEEVAL
---------- ---------- --------
10111 10235000 Good
10111 10285858 Fair
10112 10288497
10112 10092464 Fair
10113 10235000
10114 10128018 Terrible
10114 10288497
10115 10092464 Terrible
10115 10128018 Bad
10116 10128018
10118 10288497 Bad
10118 10836444 Fair
10119 10285858
10120 10412445 Mediocre
10121 10836444
10122 10285858 Good
10123 10412445 Mediocre
10125 10095146
【问题讨论】:
Oracle != mysql,我修复了你的标签。 这是case EXPRESSION,不是case语句... 【参考方案1】:您需要一个ELSE
选项来处理不匹配的情况。使用TO_CHAR
将所有值获取到相同的数据类型。
SELECT event_id,
trainee_id,
CASE eval
WHEN 0 THEN 'Terrible'
WHEN 1 THEN 'Bad'
WHEN 2 THEN 'Mediocre'
WHEN 3 THEN 'Fair'
WHEN 4 THEN 'Good'
ELSE TO_CHAR(eval)
END
FROM booking;
【讨论】:
这仍然给我“不一致的数据类型:预期的 CHAR 得到 NUMBER”错误。TO_CHAR()
应该返回 VARCHAR2
,而不是 NUMBER
。我不明白它是如何导致该错误的。【参考方案2】:
只需使用'5'
:
SELECT event_id,
trainee_id,
(CASE eval
WHEN 0 THEN 'Terrible'
WHEN 1 THEN 'Bad'
WHEN 2 THEN 'Mediocre'
WHEN 3 THEN 'Fair'
WHEN 4 THEN 'Good'
WHEN 5 THEN '5'
END
)
FROM booking;
或者,您可以使用显式 cast()
和默认值 else
:
SELECT event_id,
trainee_id,
(CASE eval
WHEN 0 THEN 'Terrible'
WHEN 1 THEN 'Bad'
WHEN 2 THEN 'Mediocre'
WHEN 3 THEN 'Fair'
WHEN 4 THEN 'Good'
ELSE cast(eval as varchar2(255))
END
)
FROM booking;
我鼓励您使用显式转换。在执行隐式转换时,SQL 可能容易出现难以调试的错误。
【讨论】:
这会起作用,除非我需要这样做,因为可能会出现更多使用 0-4 以外的数字的情况。所以也许如果有 6、7、8、9 等。我不想在查询中写出每一个数字。 @Tootally 。 . .然后使用第二个查询。 @GordonLinoff,我相信在 Oracle SQLCASE
语句中使用 ELSE
而不是 DEFAULT
。
@DavidFaber 。 . .那是因为这是标准,也是所有其他数据库所做的。我不知道自己在想什么,或者至少不知道为什么我的手指在打字。【参考方案3】:
如果您不介意您的查询是特定于 Oracle 的,您也可以使用 DECODE()
函数:
SELECT course_id, student_id
, DECODE( eval, 0, 'Terrible', 1, 'Bad', 2, 'Mediocre', 3, 'Fair', 4, 'Good', TO_CHAR(eval) )
FROM booking;
在此实例中比 CASE
节省了一些输入,并且格式化也更容易一些。
第三种选择是将评估分数及其描述存储在单独的表中,然后连接(使用外连接)以获取描述:
SELECT b.course_id, b.student_id, COALESCE(es.eval_desc, TO_CHAR(b.eval))
FROM booking b, eval_scores es
WHERE b.eval = es.eval(+)
【讨论】:
以上是关于CASE 语句将 NUMBER 转换为 CHAR,但在 Oracle SQL 中保留原始 NUMBER 的 ELSE的主要内容,如果未能解决你的问题,请参考以下文章
将嵌套解码转换为等效的 CASE 语句(需要从 Oracle 转换为 PostgreSQL)
无法将类型为“System.Decimal”的对象强制转换为类型“System.Char[]”。