《Oracle 入门教程》第 09 篇 CASE 表达式
文章目录
- 9.1 CASE 表达式
- 9.1.1 简单 CASE 表达式
- 9.1.2 搜索 CASE 表达式
- 9.2 COALESCE 函数
- 9.3 NULLIF 函数
- 9.4 NVL 函数
- 9.5 NVL2 函数
- 9.6 DECODE 函数
Oracle 中的 CASE 表达式可以根据不同条件产生不同的结果,实现类似于编程语言中的 IF-THEN-ELSE 逻辑功能。例如,根据员工的 KPI 计算相应的涨薪幅度,根据考试成绩评出优秀、良好、及格等。
COALESCE 和 NULLIF 函数是两个简写形式的 CASE 表达式。另外,Oracle 还提供了专有的 NVL、NVL2 以及 DECODE 函数。
9.1 CASE 表达式
CASE 表达式支持两种形式:简单 CASE 表达式和搜索 CASE 表达式。
9.1.1 简单 CASE 表达式
简单 CASE 表达式的语法如下:
CASE expressionWHEN value1 THEN result1WHEN value2 THEN result2...[ELSE default_result]
END
表达式的计算过程如下图所示:
首先计算 expression 的值;然后依次与 WHEN 列表中的值(value1,value2,…)进行比较,找到第一个相等的值并返回对应的结果(result1,result2,…);如果没有找到相等的值,返回 ELSE 中的默认结果;如果此时没有指定 ELSE,返回 NULL 值。
以下语句使用简单 CASE 表达式将员工的部门编号显示为相应的部门名称:
SELECT emp_name AS "员工姓名",CASE dept_idWHEN 1 THEN '行政管理部'WHEN 2 THEN '人力资源部'WHEN 3 THEN '财务部'WHEN 4 THEN '研发部'WHEN 5 THEN '销售部'WHEN 6 THEN '保卫部'ELSE '其他部门'END AS "所在部门"
FROM employee;
员工姓名|所在部门 |
------|--------|
刘备 |行政管理部|
关羽 |行政管理部|
张飞 |行政管理部|
...
邓芝 |销售部 |
简雍 |销售部 |
孙乾 |销售部 |
首先,判断部门编号是否等于 1,等于就显示为“行政管理部”;否则,如果部门编号等于 2, 显示为“人力资源部”;依次类推;如果部门编号不等于 1 到 6 中的任何值,显示为“其他部门”。
CASE 表达式的一个常见应用就是实现表的行列转换。创建以下学生成绩表:
-- 创建成绩表 t_case,sname 为学生姓名,cname 为课程名称,score 为考试成绩
CREATE TABLE t_case(sname varchar(10), cname varchar(10), score int);-- 插入测试数据
INSERT INTO t_case(sname, cname, score) VALUES ('张三', '语文', 80);
INSERT INTO t_case(sname, cname, score) VALUES ('李四', '语文', 77);
INSERT INTO t_case(sname, cname, score) VALUES ('王五', '语文', 91);
INSERT INTO t_case(sname, cname, score) VALUES ('张三', '数学', 85);
INSERT INTO t_case(sname, cname, score) VALUES ('李四', '数学', 90);
INSERT INTO t_case(sname, cname, score) VALUES ('王五', '数学', 60);
INSERT INTO t_case(sname, cname, score) VALUES ('张三', '英语', 81);
INSERT INTO t_case(sname, cname, score) VALUES ('李四', '英语', 69);
INSERT INTO t_case(sname, cname, score) VALUES ('王五', '英语', 82);
该表中的数据如下:
SELECT *
FROM t_case;
sname |cname |score|
------|-------|-----|
张三 |语文 | 80|
李四 |语文 | 77|
王五 |语文 | 91|
张三 |数学 | 85|
李四 |数学 | 90|
王五 |数学 | 60|
张三 |英语 | 81|
李四 |英语 | 69|
王五 |英语 | 82|
接下来我们利用 CASE 表达式将其转换为按列显示的形式:
SELECT sname,sum(CASE cname WHEN '语文' THEN score ELSE 0 END) AS "语文",sum(CASE cname WHEN '数学' THEN score ELSE 0 END) AS "数学",sum(CASE cname WHEN '英语' THEN score ELSE 0 END) AS "英语"
FROM t_case
GROUP BY sname;
sname |语文|数学|英语|
------|---|---|---|
张三 | 80| 85| 81|
李四 | 77| 90| 69|
王五 | 91| 60| 82|
第一个 CASE 表达式用于获取学生的语文成绩,cname 等于“语文”就返回考试成绩,不是“语文”就记为 0 分;第二个和第三个 CASE 表达式分别用于获取数学和英语成绩。然后,使用 SUM 汇总函数和 GROUP BY 分组操作将每个学生的成绩合并成一条记录。
简单 CASE 表达式使用的是等值比较(=),只能处理简单的逻辑。如果想要进行复杂的逻辑处理,例如根据考试成绩评出优秀、良好、及格等,或者判断表达式的值是否为空,就需要使用更加强大的搜索 CASE 表达式。
9.1.2 搜索 CASE 表达式
搜索 CASE 表达式的语法如下:
CASEWHEN condition1 THEN result1WHEN condition2 THEN result2...[ELSE default_result]
END
表达式的计算过程如下图所示:
按照顺序依次计算每个分支中的条件(condition1,condition2,…),找到第一个结果为真的分支并返回相应的结果(result1,result2,…);如果没有任何条件为真,返回 ELSE 中的默认结果;如果此时没有指定 ELSE,返回 NULL 值。
所有的简单 CASE 表达式都可以替换为等价的搜索 CASE 表达式。我们可以将上一节的示例改写如下:
SELECT emp_name AS "员工姓名",CASEWHEN dept_id = 1 THEN '行政管理部'WHEN dept_id = 2 THEN '人力资源部'WHEN dept_id = 3 THEN '财务部'WHEN dept_id = 4 THEN '研发部'WHEN dept_id = 5 THEN '销售部'WHEN dept_id = 6 THEN '保卫部'ELSE '其他部门'END AS "所在部门"
FROM employee;
首先,判断部门编号等于 1 是否成立(为真),成立就显示为“行政管理部”;否则,判断部门编号等于 2 是否成立, 成立就显示为“人力资源部”;依次类推;如果部门编号不等于 1 到 6 中的任何值,显示为“其他部门”。
以下查询按照考试分数对成绩进行评价:
SELECT sname AS "学生姓名",cname AS "学科名称",CASEWHEN score >= 90 THEN '优秀'WHEN score >= 80 THEN '良好'WHEN score >= 70 THEN '中等'WHEN score >= 60 THEN '及格'ELSE '不及格'END AS "考试成绩"
FROM t_case;
学生姓名|学科名称|考试成绩|
-------|------|-------|
张三 |语文 |良好 |
李四 |语文 |中等 |
王五 |语文 |优秀 |
张三 |数学 |良好 |
李四 |数学 |优秀 |
王五 |数学 |及格 |
张三 |英语 |良好 |
李四 |英语 |及格 |
王五 |英语 |良好 |
CASE 表达式除了可以用于 SELECT 列表,也可以出现在其他子句中,例如 WHERE、GROUP BY、ORDER BY 等。以下语句使用 CASE 表达式实现了自定义的排序规则:
SELECT emp_name,CASE emp_nameWHEN '刘备' THEN 1WHEN '关羽' THEN 2WHEN '张飞' THEN 3ELSE 99END AS num
FROM employee
ORDER BY CASE emp_nameWHEN '刘备' THEN 1WHEN '关羽' THEN 2WHEN '张飞' THEN 3ELSE 99END;
EMP_NAME|NUM|
--------+---+
刘备 | 1|
关羽 | 2|
张飞 | 3|
孙丫鬟 | 99|
...
关平 | 99|
我们通过 CASE 表达式将“刘备”编号为 1,“关羽”编号为 2,“张飞”编号为 3,其他人员编号为 99。
9.2 COALESCE 函数
COALESCE(expr1, …) 函数返回参数中第一个非空的值,它的等价 CASE 表达式如下:
CASEWHEN expr1 IS NOT NULL THEN expr1WHEN expr2 IS NOT NULL THEN expr2WHEN expr3 IS NOT NULL THEN expr3...
END
例如:
SELECT coalesce(NULL, NULL, 1), coalesce(NULL, NULL, NULL)
FROM dual;
COALESCE(NULL,NULL,1)|COALESCE(NULL,NULL,NULL)|
---------------------+------------------------+1| |
9.3 NULLIF 函数
NULLIF(expr1,expr2) 函数的处理逻辑如下:如果表达式 expr1 和 expr2 相等,返回 NULL;否则,返回 expr1 的值。NULLIF 函数可以使用等价的 CASE 表达式进行表示:
CASEWHEN expr1 = expr2 THEN NULLELSE expr1
END
NULLIF 函数的一个常见用途是防止除零错误:
-- 除零错误
SELECT 1 / 0
FROM dual;
SQL 错误 [1476] [22012]: ORA-01476: 除数为 0SELECT 1 / NULLIF(0 , 0)
FROM dual;
1/NULLIF(0,0)|
-------------+|
第一个语句会产生除零错误,第二个语句返回 NULL。
9.4 NVL 函数
NVL(expr1, expr2) 函数,它用于返回第一个非空的参数值,相当于只有两个参数的 COALESCE 函数。
以下查询返回了员工的总收入:
SELECT emp_name,salary*12 + NVL(bonus, 0) AS "年收入"
FROM employee;
EMP_NAME|年收入 |
--------+------+
刘备 |370000|
关羽 |322000|
张飞 |298000|
诸葛亮 |296000|
黄忠 | 96000|
魏延 | 90000|
...
9.5 NVL2 函数
NVL2(expr1, expr2, expr3) 函数包含三个参数,如果第一个参数不为空,返回第二个参数的值;否则,返回第三个参数的值。以下查询同样返回员工的总收入:
SELECT emp_name,NVL2(bonus, salary*12 + bonus, salary*12) AS "年收入"
FROM employee;
9.6 DECODE 函数
DECODE 函数可以实现类似于简单 CASE 表达式的功能:
DECODE(expression, value1, result1, value2, result2, ...[, default_result ])
该函数依次比较表达式 expression 与 valueN 的值,如果找到相等的值就返回对应的 resultN;如果没有匹配到任何相等的值,返回默认结果 default_result;如果此时没有提供 default_result,返回 NULL 值。
以下语句利用 DECODE 函数将员工的部门编号显示为相应的名称:
SELECT emp_name,DECODE(dept_id, 1, '行政管理部',2, '人力资源部',3 ,'财务部',4, '研发部',5, '销售部',6, '保卫部','其他部门') AS department
FROM employee;
该查询的结果与前文中的简单 CASE 表达式示例相同。DECODE 是 Oracle 专有函数,推荐大家使用标准的 CASE 表达式。
《Oracle 入门教程》第 09 篇 CASE 表达式相关推荐
- 《Oracle 入门教程》第 01 篇 专栏介绍
文章目录 专栏背景 专栏内容 专栏寄语 大家好,我是只谈技术不剪发的 Tony 老师.欢迎来到我的专栏<Oracle 入门教程>!本专栏主要面向 Oracle 数据库的初学者,包括初级 D ...
- Linux Capabilities 入门教程--进阶实战篇
该系列文章总共分为三篇: Linux Capabilities 入门教程:概念篇 Linux Capabilities 入门教程:基础实战篇 Linux Capabilities 入门教程:进阶实战篇 ...
- Systemd入门教程:命令篇
Systemd入门教程:命令篇 转自:http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-commands.html 作者: 阮一峰 日期: ...
- Systemd 入门教程:实战篇
Systemd 入门教程:实战篇 原文出处: 阮一峰(@ruanyf) http://blog.jobbole.com/98671/?utm_source=blog.jobbole.com& ...
- Linux Capabilities 入门教程--基础实战篇
该系列文章总共分为三篇: Linux Capabilities 入门教程:概念篇 Linux Capabilities 入门教程:基础实战篇 Linux Capabilities 入门教程:进阶实战篇 ...
- 深度学习小白入门教程-基础环境篇
深度学习小白入门教程-基础环境篇 如有图片显示失败,请回小主主页查看~ Anaconda 安装包下载方式一:官网(科学上网比较慢,不推荐) 安装包下载方式二:清华镜像(推荐) 具体安装步骤(跟着箭头来 ...
- 九宫怎么排列和使用_广告视频配音剪映零基础入门教程第二十三篇:剪辑之九宫格教程...
朋友圈最火九宫格视频你们知道是怎样制作的吗?我们常常在玩朋友圈的时候想用九宫格照片,但是你们有没有遇到这种情况,想玩九宫格却发现找不到那么多能用的照片,那这时候怎么办呢?玩腻了平常图片的发法,今天我们 ...
- 《零基础看得懂的C++入门教程 》——(3)表达式花样挺多鸭
一.学习目标 了解变量之间的计算 了解什么是表达式 了解什么是自增.自减 目录 预备第一篇,使用软件介绍在这一篇,C++与C使用的软件是一样的,查看这篇即可:<软件介绍> 想了解编译原理和 ...
- 【SQL进阶教程】第一章 case表达式
本系列基于<SQL进阶教程>(如下图)学习,实现了书中代码及练习题代码.PS:电子书请大家各自默默脚本之家. [知识点1]case表达式概述 Case表达式有简单case表达式和搜索cas ...
最新文章
- 自从用完 Gradle 后,有点嫌弃 Maven 了!
- 关于表单的java的程序_JAVA BOT程序模拟人类用户填写表单 并 发送
- 几种特征选择方法的比较,孰好孰坏?
- 深度学习与芯片之间的羁绊往事
- 什么是 Delta 文件
- 2.登录linun 输入密码登录不进去 进入单用户模式 修改 然后reboot
- java监控数据库的增量_【安德鲁斯】基于脚本的数据库quot;增量更新quot;,如果不改变,每次更新java代码、!...
- 理解 RIPv1使用广播更新路由与RIPv2使用组播更新路由的区别
- Linux 中断实验
- c#物联网_C# 基础知识系列- 16 开发工具篇
- Hdu 1026 Ignatius and the Princess I
- Spring Security 11 种过滤器介绍
- vs2008 MFC工程建立
- Matlab图像显示
- 计算机控制系统编程语言,可编程控制器常用的几种编程语言
- linux核显显示独显内容,Linux驱动显示Intel第12代核显新特性:显示状态缓存
- 锂电池基本原理解析:充电及放电机制
- Xcode7 网络请求报错:The resource could not be loaded be
- vue的一些心得总结
- 5GCPE如何支持4G物联网卡(修改IMEI)
热门文章
- python time.sleep精确延时,Python time sleep()– time.sleep()方法的一站式解决方案
- Linux基础入门和帮助
- html博客图文设计,设计基本功!帮你掌握图文排版的5个小技巧—UI博客精选
- 【wifi测试】一周总结,新年展望(2013年1月6号更新)
- 计算机和人类哪个聪明相关资料,人脑和电脑哪个聪明脑筋急转弯
- Spring boot mybatis 打印SQL语句
- ERROR: Invalid HADOOP_MAPRED_HOME
- 几个思路教你制定性能测试方案
- 2.《新生——七年就是一辈子》 ——李笑来
- IBatis之Iterate