百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

什么是 SQL CASE 表达式,如何使用 SQL CASE 表达式

mhr18 2024-10-18 07:03 27 浏览 0 评论

目录

  • 一、什么是 CASE 表达式
  • 二、CASE 表达式的语法
  • 三、CASE 表达式的使用方法
  • 四、CASE 表达式的书写位置

本文介绍 SQL CASE 表达式,它是 SQL 中数一数二的重要功能,CASE 表达式的语法分为简单 CASE 表达式搜索 CASE 表达式两种。

本文重点

CASE 表达式分为简单 CASE 表达式和搜索 CASE 表达式两种。搜索 CASE 表达式包含简单 CASE 表达式的全部功能。

虽然 CASE 表达式中的 ELSE 子句可以省略,但为了让 SQL 语句更加容易理解,还是希望大家不要省略。

CASE 表达式中的 END 不能省略。

使用 CASE 表达式能够将 SELECT 语句的结果进行组合。

虽然有些 DBMS 提供了各自特有的 CASE 表达式的简化函数,例如 Oracle 中的 DECODE 和 MySQL 中的 IF,等等,但由于它们并非通用的函数,功能上也有些限制,因此有些场合无法使用。

一、什么是 CASE 表达式

本文将要学习的 CASE 表达式,和“1 + 1”或者“120 / 4”这样的表达式一样,是一种进行运算的功能。这就意味着 CASE 表达式也是函数的一种。

它是 SQL 中数一数二的重要功能,希望大家能够在这里好好学习掌握。

CASE 表达式是在区分情况时使用的,这种情况的区分在编程中通常称为 (条件)分支 [1]。

二、CASE 表达式的语法

CASE 表达式的语法分为简单 CASE 表达式搜索 CASE 表达式两种。但是,由于搜索 CASE 表达式包含了简单 CASE 表达式的全部功能,因此本文只会介绍搜索 CASE 表达式。

想要了解简单 CASE 表达式语法的读者,可以参考本文末尾的“简单 CASE 表达式”专栏。

下面就让我们赶快来学习一下搜索 CASE 表达式的语法吧。

语法 16 搜索 CASE 表达式

CASE WHEN <求值表达式> THEN <表达式>     WHEN <求值表达式> THEN <表达式>     WHEN <求值表达式> THEN <表达式>       .       .       .     ELSE <表达式>END

WHEN 子句中的“<求值表达式>”就是类似“列 = 值”这样,返回值为真值(TRUE/FALSE/UNKNOWN)的表达式。

我们也可以将其看作使用 =!= 或者 LIKEBETWEEN 等 谓词 编写出来的表达式。

CASE 表达式会从对最初的 WHEN 子句中的“<求值表达式>”进行求值开始执行。

所谓求值,就是要调查该表达式的真值是什么。如果结果为真(TRUE),那么就返回 THEN 子句中的表达式,CASE 表达式的执行到此为止。

如果结果不为真,那么就跳转到下一条 WHEN 子句的求值之中。如果直到最后的 WHEN 子句为止返回结果都不为真,那么就会返回 ELSE 中的表达式,执行终止。

CASE 表达式名称中的“表达式”我们也能看出来,上述这些整体构成了一个表达式。并且由于表达式最终会返回一个值,因此 CASE 表达式在 SQL 语句执行时,也会转化为一个值。

虽然使用分支众多的 CASE 表达式编写几十行代码的情况也并不少见,但是无论多么庞大的 CASE 表达式,最后也只会返回类似“1”或者“'渡边先生'”这样简单的值。

三、CASE 表达式的使用方法

那么就让我们来学习一下 CASE 表达式的具体使用方法吧。

例如我们来考虑这样一种情况,现在 Product(商品)表中包含衣服、办公用品和厨房用具 3 种商品类型,请大家考虑一下怎样才能够得到如下结果。

A :衣服B :办公用品C :厨房用具

因为表中的记录并不包含“A :”或者“B :”这样的字符串,所以需要在 SQL 中进行添加。我们可以使用 SQL 常用的函数 中学过的字符串连接函数“||”来完成这项工作。

剩下的问题就是怎样正确地将“A :”“B :”“C :”与记录结合起来。这时就可以使用 CASE 表达式来实现了(代码清单 41)。

代码清单 41 通过 CASE 表达式将 A ~ C 的字符串加入到商品种类当中

SELECT product_name,       CASE WHEN product_type = '衣服'            THEN 'A:' || product_type            WHEN product_type = '办公用品'            THEN 'B:' || product_type            WHEN product_type = '厨房用具'            THEN 'C:' || product_type            ELSE NULL       END AS abc_product_type  FROM Product;

执行结果:

 product_name | abc_product_type--------------+------------------ T恤衫        | A :衣服 打孔器       | B :办公用品 运动T恤      | A :衣服 菜刀         | C :厨房用具 高压锅       | C :厨房用具 叉子         | C :厨房用具 擦菜板       | C :厨房用具 圆珠笔       | B :办公用品

6 行 CASE 表达式代码最后只相当于 1 列(abc_product_type)而已,大家也许有点吃惊吧!与商品种类(product_type)的名称相对应,CASE 表达式中包含了 3 条 WHEN 子句分支。

最后的 ELSE NULL 是“上述情况之外时返回 NULL”的意思。

ELSE 子句指定了应该如何处理不满足 WHEN 子句中的条件的记录,NULL 之外的其他值或者表达式也都可以写在 ELSE 子句之中。

但由于现在表中包含的商品种类只有 3 种,因此实际上有没有 ELSE 子句都是一样的。

ELSE 子句也可以省略不写,这时会被默认为 ELSE NULL。但为了防止有人漏读,还是希望大家能够显式地写出 ELSE 子句。

法则 3

虽然 CASE 表达式中的 ELSE 子句可以省略,但还是希望大家不要省略。

此外,CASE 表达式最后的“END”是不能省略的,请大家特别注意不要遗漏。忘记书写 END 会发生语法错误,这也是初学时最容易犯的错误。

法则 4

CASE 表达式中的 END 不能省略。

四、CASE 表达式的书写位置

CASE 表达式的便利之处就在于它是一个表达式。

之所以这么说,是因为表达式可以书写在任意位置,也就是像“1 + 1”这样写在什么位置都可以的意思。

例如,我们可以像下面这样利用 CASE 表达式将 SELECT 语句的结果中的行和列进行互换。

执行结果:

sum_price_clothes | sum_price_kitchen | sum_price_office------------------+-------------------+-----------------             5000 |             11180 |              600

上述结果是根据商品种类计算出的销售单价的合计值,通常我们将商品种类列作为 GROUP BY 子句的聚合键来使用,但是这样得到的结果会以“行”的形式输出,而无法以列的形式进行排列(代码清单 42)。

代码清单 42 通常使用 GROUP BY 也无法实现行列转换

SELECT product_type,       SUM(sale_price) AS sum_price  FROM Product GROUP BY product_type;

执行结果:

 product_type | sum_price--------------+---------- 衣服         |      5000 办公用品     |       600 厨房用具     |     11180

我们可以像代码清单 43 那样在 SUM 函数中使用 CASE 表达式来获得一个 3 列的结果。

代码清单 43 使用 CASE 表达式进行行列转换

-- 对按照商品种类计算出的销售单价合计值进行行列转换SELECT SUM(CASE WHEN product_type = '衣服'                THEN sale_price ELSE 0 END) AS sum_price_clothes,       SUM(CASE WHEN product_type = '厨房用具'                THEN sale_price ELSE 0 END) AS sum_price_kitchen,       SUM(CASE WHEN product_type = '办公用品'                THEN sale_price ELSE 0 END) AS sum_price_office  FROM Product;

在满足商品种类(product_type)为“衣服”或者“办公用品”等特定值时,上述 CASE 表达式输出该商品的销售单价(sale_price),不满足时输出 0

对该结果进行汇总处理,就能够得到特定商品种类的销售单价合计值了。

在对 SELECT 语句的结果进行编辑时,CASE 表达式能够发挥较大作用。

专栏

简单 CASE 表达式

CASE 表达式分为两种,一种是本文学习的“搜索 CASE 表达式”,另一种就是其简化形式——“简单 CASE 表达式”。

简单 CASE 表达式比搜索 CASE 表达式简单,但是会受到条件的约束,因此通常情况下都会使用搜索 CASE 表达式。在此我们简单介绍一下其语法结构。

简单 CASE 表达式的语法如下所示。

语法 A 简单 CASE 表达式

CASE <表达式> WHEN <表达式> THEN <表达式> WHEN <表达式> THEN <表达式> WHEN <表达式> THEN <表达式> . . . ELSE <表达式>END

与搜索 CASE 表达式一样,简单 CASE 表达式也是从最初的 WHEN 子句开始进行,逐一判断每个 WHEN 子句直到返回真值为止。

此外,没有能够返回真值的 WHEN 子句时,也会返回 ELSE 子句指定的表达式。两者的不同之处在于,简单 CASE 表达式最初的“CASE<表达式>”也会作为求值的对象。

下面就让我们来看一看搜索 CASE 表达式和简单 CASE 表达式是如何实现相同含义的 SQL 语句的。

将代码清单 41 中的搜索 CASE 表达式的 SQL 改写为简单 CASE 表达式,结果如下所示(代码清单 A)。

代码清单 A 使用 CASE 表达式将字符串 A ~ C 添加到商品种类中

-- 使用搜索CASE表达式的情况(重写代码清单6-41)SELECT product_name, CASE WHEN product_type = '衣服' THEN 'A :' | |product_type WHEN product_type = '办公用品' THEN 'B :' | |product_type WHEN product_type = '厨房用具' THEN 'C :' | |product_type ELSE NULL END AS abc_product_type FROM Product; -- 使用简单CASE表达式的情况SELECT product_name, CASE product_type WHEN '衣服' THEN 'A :' || product_type WHEN '办公用品' THEN 'B :' || product_type WHEN '厨房用具' THEN 'C :' || product_type ELSE NULL END AS abc_product_type FROM Product;

像“CASE product_type”这样,简单 CASE 表达式在将想要求值的表达式(这里是列)书写过一次之后,就无需在之后的 WHEN 子句中重复书写“product_type”了。

虽然看上去简化了书写,但是想要在 WHEN 子句中指定不同列时,简单 CASE 表达式就无能为力了。

专栏

特定的 CASE 表达式

由于 CASE 表达式是标准 SQL 所承认的功能,因此在任何 DBMS 中都可以执行。

但是,有些 DBMS 还提供了一些特有的 CASE 表达式的简化函数,例如 Oracle 中的 DECODE、MySQL 中的 IF 等。

使用 Oracle 中的 DECODE 和 MySQL 中的 IF 将字符串 A ~ C 添加到商品种类(product_type)中的 SQL 语句请参考代码清单 B。

代码清单 B 使用 CASE 表达式的特定语句将字符串 A ~ C 添加到商品种类中

Oracle

-- Oracle中使用DECODE代替CASE表达式SELECT product_name, DECODE(product_type, '衣服', 'A :' || product_type, '办公用品', 'B :' || product_type, '厨房用具', 'C :' || product_type, NULL) AS abc_product_typeFROM Product;

MySQL

-- MySQL中使用IF代替CASE表达式SELECT product_name, IF( IF( IF(product_type = '衣服', CONCAT('A :', product_type), NULL) IS NULL AND product_type = '办公用品', CONCAT('B :', product_type), IF(product_type = '衣服', CONCAT('A :', product_type), NULL)) IS NULL AND product_type = '厨房用具', CONCAT('C :', product_type), IF( IF(product_type = '衣服', CONCAT('A :', product_type), NULL) IS NULL AND product_type = '办公用品', CONCAT('B :', product_type), IF(product_type = '衣服', CONCAT('A :', product_type), NULL))) AS abc_product_typeFROM Product;

但上述函数只能在特定的 DBMS 中使用,并且能够使用的条件也没有 CASE 表达式那么丰富,因此并没有什么优势。希望大家尽量不要使用这些特定的 SQL 语句。

相关推荐

甲骨文签署多项大型云协议,其一未来可贡献超300亿美元年收入

IT之家7月1日消息,根据甲骨文Oracle当地时间6月30日向美国证券交易委员会(SEC)递交的FORM8-K文件,该企业在始于2025年6月1日的202...

甲骨文获TEMU巨额合同,后者大部分基础设施将迁移至Oracle云

IT之家6月23日消息,Oracle甲骨文创始人、董事长兼首席技术官LarryEllison(拉里埃里森)在本月早些时候的2025财年第四财季和全财年财报电话会议上表示,Oracle...

Spring Boot 自定义数据源设置,这些坑你踩过吗?

你在使用SpringBoot进行后端开发的过程中,是不是也遇到过这样的问题:项目上线后,数据库连接总是不稳定,偶尔还会出现数据读取缓慢的情况,严重影响了用户体验。经过排查,发现很大一部分原因竟然...

一个开箱即用的代码生成器(一个开箱即用的代码生成器是什么)

今天给大家推荐一个好用的代码生成器,名为renren-generator,该项目附带前端页面,可以很方便的选择我们所需要生成代码的表。首先我们通过git工具克隆下来代码(地址见文末),导入idea。...

低代码建模平台-数据挖掘平台(低代码平台的实现方式)

现在来看一下数据连接。·这里是管理数据连接的空间,点击这里可以新增一个数据连接。·输入连接名称,然后输入url,是通过gdbc的方式去连接的数据库,目前是支持mysql、oracle以及国产数据库达梦...

navicat 17.2.7连接oracle数据库提示加载oracle库失败

系统:macOS15.5navicat版本:navicatpremiumlite17.2.7连接oracle测试报错:加载oracle库失败【解决办法】:放达里面找到程序,显示简介里面勾选“使...

开源“Windows”ReactOS更新:支持全屏应用

IT之家6月17日消息,ReactOS团队昨日(6月16日)在X平台发布系列推文,公布了该系统的最新进展,包括升级Explorer组件,支持全屏应用,从Wine项目引入了...

SSL 推出采用全模拟内置混音技术的模拟调音台Oracle

英国调音台传奇品牌SolidStateLogic宣布推出Oracle——一款采用全模拟内置混音技术的调音台,在紧凑的AWS尺寸机箱内集成了大型调音台的功能。该调音台提供24输入和...

47道网络工程师常见面试题,看看有没有你不会的!

你们好,我的网工朋友。网络工程师面试的时候,都会被问到什么?这个问题其实很泛,一般来说,你肯定要先看明白岗位需求写的是什么。基本上都是围绕公司需要的业务去问的。但不可否认的是,那些最基础的概念,多少也...

汉得信息:发布EBS系统安装启用JWS的高效解决方案

e公司讯,从汉得信息获悉,近日,微软官方宣布InternetExplorer桌面应用程序将于2022年6月15日正式停用。目前大部分客户都是使用IE浏览器打开EBS的Form界面,IE停用后,只能使...

36.9K star ! 推荐一个酷炫低代码开发平台!功能太强!

前言最近在逛github,看看能不能搜罗到一些对自己有帮助的开源软件。不经意间看到一个高star的java开源项目:jeecg-boot。进入在线演示版一看,感叹实在是太牛了!此开源项目不管是给来学习...

Linux新手入门系列:Linux下jdk安装配置

本系列文章是把作者刚接触和学习Linux时候的实操记录分享出来,内容主要包括Linux入门的一些理论概念知识、Web程序、mysql数据库的简单安装部署,希望能够帮到一些初学者,少走一些弯路。注意:L...

手把手教你在嵌入式设备中使用SQLite3

摘要:数据库是用来存储和管理数据的专用软件,使得管理数据更加安全,方便和高效。数据库对数据的管理的基本单位是表(table),在嵌入式linux中有时候它也需要用到数据库,听起来好难,其实就是几个函数...

JAVA语言基础(java语言基础知识)

一、计算机的基本概念什么是计算机?计算机(Computer)全称:电子计算机,俗称电脑。是一种能够按照程序运行、自动高速处理海量数据的现代化智能电子设备。由硬件和软件组成、没有安装过任何软件的计算机称...

再见 Navicat!一款开源的 Web 数据库管理工具!

大家好,我是Java陈序员。在日常的开发工作中,常常需要与各种数据库打交道。而为了提高工作效率,常常会使用一些可视化工具进行操作数据库。今天,给大家介绍一款开源的数据库管理工具,无需下载安装软件,基...

取消回复欢迎 发表评论: