一、简介   

  官方定义CASE是一种表达式,它基于某种格式,按照格式去编写表达式,其中表达式的逻辑是:指定特定的值与条件列表去匹配,返回对应的值。

  CASE表达式类似我们编程语言中的 if else 和 switch 的逻辑,那么久代表我们可以拿一些值做判断,做出与之对应的处理。

  CASE表达式的用途很广,在开发中使用率也很高,所以个人觉得有必要把这个基础的知识点吃透。CASE表达式用的最多的就是SELECT查询语句中,但也不局限于此。

  实际上CASE表达式可以用于允许使用有效表达式的任意语句或子句中。例如SELECT、UPDATE、DELETE、和SET等语句以及select_list、IN、WHERE、ORDER BY、HAVING等子句中使用CASE。

  CASE表达式有两种格式:

    1.简单格式:用一个值或者属性或者表达式,去与一个条件列表做等值判断,匹配到相等的,则返回条件列表对应的结果。

    2.搜索格式:像极了编程语言中if else 和 switch,在一个或多个布尔表达式中匹配一个结果为true的,然后返回对应的处理结果。

二、语法初探

--简单格式 CASE表达式
CASE input_expression
WHEN when_expression THEN result_expression [ ...n ]
[ ELSE else_result_expression ]
END --搜索模式
CASE
WHEN Boolean_expression THEN result_expression [ ...n ]
[ ELSE else_result_expression ]
END

input_expression(简单格式):

指定一个有效的表达式(可以是常量、变量、列属性),只要表达式返回的是单个数据值。

when_expression(简单格式):

在简单格式中,此处填写的内容是用于和input_expression表达式进行等值比较的。when_expression的内容可以是任何有效的表达式,可以指定多个。

input_expression和when_expression的注意事项(简单格式):

在简单模式中,input_expression和when_expression表达式计算的结果值,要求数据类型必须相同,如果不满足则两个结果值必须满足隐式转换的条件。如果两个条件都不满足,则会提示“数据类型转换失败”。

result_expression:

CASE表达式匹配后返回的结果,结果可以指定任何有效的表达式。

简单格式:当 input_expression = when_expression的计算结果相等时,将其返回。

搜索格式:当Boolean_expression表达式计算结果为true时,将其返回。

 else_result_expression:

一个可选的部分,可以指定有效的表达式,逻辑和编程语言中的ELSE是一个逻辑。当指定值和比较值列表没有一个匹配为true时,将其作为结果返回。

如果没有指定else_result_expression表达式并且匹配结果都不为true时,那么最终返回NULL。

Boolean_expression(搜索格式):

使用搜索格式时的写法,可以指定一个有效的布尔表达式,并且可以指定多个。例如,“age>18”、“score between 60 and 100”等。

三、关于CASE表达式返回值的数据类型

  在编写CASE表达式的时候,往往我们要编写多个对比的条件列表,那么就意味着对应也有多个返回结果。

  当CASE表达式匹配某个条件成功时,会返回相应的处理结果,那么在这个返回结果的数据类型上有一个细节。

  这个细节的定论是:当CASE表达式有多个可能返回的结果列表时,匹配成功的这个结果的数据类型,会从结果列表中(包括else部分),参照SQL Server数据类型优先级的规则,选择一个优先级最高的作为返回结果的数据类型。正常的思维逻辑是返回的结果值和数据类型是对应的。例如,1代表int类型、'a'代表字符类型。但是实际结果往往让我们意外,示例图如下:

  (如果CASE表达式匹配返的结果的数据类型)和(在所有结果中根据数据类型优先级规则确定了的数据类型)不相同,并且也不符合隐式转换,那么执行的时候就会出现错误。

   示例图:

   

    如果 返回结果'二'写成'2',那么就符合隐式转换,查询可以成功执行。

    

 四、CASE表达式的运用示例

A.在SELECT语句中使用简单格式

简单格式的工作逻辑:根据CASE关键字后指定的表达式,去和一个或多个when子句中的表达式进行比较,这种比较是等值比较判断两者是否相等。

业务场景:某旅游网站想查询出其下合作的酒店信息,酒店信息来自主要酒店表,用户想要知道酒店的对应星级名称,因为星级就那么固定几个(1-5),所以在建的时候没有必要建立主外键关联表,

     对应的数据列存储的1-5的数字。显然直接查询显示不太友好和明确,对于这种特定标识特定的语义化的情况,就是使用CASE表达式简单格式的最佳场景。

示例代码:    

select hotelsName, address,phone,
case grade
when 1 then '一星级'
when 2 then '二星级'
when 3 then '三星级'
when 4 then '四星级'
when 5 then '五星级'
else '未知' end as grade
from Hotels

B.在SELECT语句中使用搜索格式

搜索格式的工作逻辑:指定一个或多个when子句,并在其指定布尔表达式,和对应的返回结果。

搜索格式和简单格式对比:书写结构上和简单格式相似,搜索格式在CASE关键字后没有指定表达式,而是在when子句中指定布尔表达式。

            搜索格式显然在逻辑上更灵活,而且搜索格式显然可以兼容简单格式的判断逻辑,简单格式则只局限于等值判断。   

业务场景:根据数值范围,作出逻辑的定义。某婚恋网站,想查询男性用户时根据年龄,然后根据特定逻辑的范围,对用户打上年龄化的标签。

示例代码:

select  case
when Age>18 and Age <30 then '小鲜肉'
when Age>30 and Age <45 then '熟男'
when Age>45 and Age<50 then '大叔' end ageFlag
from Student
where Gender='男'

C.在ORDER BY子句中使用CASE

业务场景:老师想查询学生的成绩信息。对于及格的(passFlag=1)学生的成绩分数想看从高到底查看,以便更好的培养尖子生。对于不及格(passFlag=0)的学生的成绩分数想从底到高查看,以便不同情况对差生进行补习。

示例代码:

select b.passFlag,a.StudentId,a.StudentName,(b.CSharp+b.SQLServerDB) as score
from Student a
inner join ScoreList b on a.StudentId=b.StudentId
order by case passFlag when 0 then (b.CSharp+b.SQLServerDB) end asc,
case passFlag when 1 then (b.CSharp+b.SQLServerDB) end desc

D.CASE表达式实现数据行专列

在这里使用CASE表达式实现数据的行专列,并不是唯一可行的方法,而是通过此示例更好的融汇贯通CASE表达式的运用。对于行转列的这种特定的操作,SQL Server提供了PIVOT的方案来解决。

CASE表达式实现行转列的方式依赖于的表结关联系:

此关联中存在一个多对多的中间表,每行行会显示课程对应考的分数。观察这种关系结构和CASE表达式的特性,运用起来实现行转为列。在个示例图中,即课程转为列,列值显示分数。

实现代码:

select a.name ,
MAX(case c.cid when 1 then b.score end) as '语文',
MAX(case c.cid when 2 then b.score end) as '数学',
MAX(case c.cid when 3 then b.score end ) as '体育'
from StudentInfo a
inner join StuCourseGrade b on a.stuId=b.stuId
inner join Curriculum c on b.cid=c.cid
group by a.name

我们分析一下查询逻辑如何进行的处理:

      

CASE表达式的更多相关文章

  1. SQL Server case表达式的用法

    ★CASE表达式是一个标量表达式,它基于条件逻辑来返回一个值.因为CASE是一个标量表达式,所以它可以应用在SELECT.WHERE.HAVING以及ORDER BY子句中. CASE表达式有两种格式 ...

  2. CASE表达式的使用

    我们在开发过程中,经常需要针对一列,基于条件逻辑来返回一个值,那么,这时候就需要使用到CASE表达式了. 例如,以下对Products表的查询就在SELECT语句中使用了CASE表达式,以生成用于描述 ...

  3. SQLServer学习笔记<>日期和时间数据的处理(cast转化格式、日期截取、日期的加减)和 case表达式

    日期和时间数据的处理. (1)字符串日期 ‘20080301’,这一串为字符串日期,但必须保证为四位的年份,两位的月份,两位的日期.例如,查询订单表日期大于‘20080301’.可以这样写: 1 se ...

  4. Sql 基于列的Case表达式

    Case表达式可以用在 Select,update ,delete ,set,in,where ,order by,having子句之后, 只是case表达式不能控制sql程序的流程,只能作为基于列的 ...

  5. 使用CASE表达式替代SQL Server中的动态SQL

    原文:使用CASE表达式替代SQL Server中的动态SQL 翻译自: http://www.mssqltips.com/sqlservertip/1455/using-the-case-expre ...

  6. [SQL] SQL 基础知识梳理(六)- 函数、谓词、CASE 表达式

    SQL 基础知识梳理(六)-  函数.谓词.CASE 表达式 目录 函数 谓词 CASE 表达式 一.函数 1.函数:输入某一值得到相应输出结果的功能,输入值称为“参数”,输出值称为“返回值”. 2. ...

  7. 楼梯T-SQL:超越基础6级:使用CASE表达式和IIF函数

     从他的楼梯到T-SQL DML,Gregory Larsen涵盖了更多的高级方面的T-SQL语言,如子查询. 有时您需要编写一个可以根据另一个表达式的评估返回不同的TSQL表达式的单个TSQL语句. ...

  8. SQL基础学习_05_函数、谓词、CASE表达式

    函数 算术函数 1. 四则运算: +.-.*./  2. ABS:求绝对值, ABS(数值) 3. MOD: 求余,MOD(被除数,除数) 4. ROUND:四舍五入,ROUND(对象数值,保留小数的 ...

  9. DML数据操作语言之谓词,case表达式

    谓词:就是返回值是真值的函数. 前面接触到的“>” “<” “=”等称为比较运算符,它们的正式名称就是比较谓词.因为它们比较之后返回的结果是真值. 由于谓词 返回的结果是一个真值 ,即tr ...

  10. CASE 表达式

    通过本篇文章我们来学习一下CASE表达式的基本使用方法. CASE表达式有简单 CASE表达式(simple case expression)和搜索 CASE表达式(searched caseexpr ...

随机推荐

  1. java多线程-ThreadLocal

    大纲: 用法 源码 一.用法 ThreadLocal是一个容器,顾名思义就是把一个变量存到线程本地. class Test { public static void main(String[] arg ...

  2. (转)PXE+kickstart无人值守安装CentOS 7

    kickstart+cobbler系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html 本文是PXE+kickstart无人值守安装CentOS ...

  3. springboot 上传图片与回显

    在网上找了很多例子,不能完全契合自己的需求,自行整理了下.需求是这样的:项目小,所以不需要单独的图片服务器,图片保存在服务器中任意的地方,并且可以通过访问服务器来获取图片.话不多说上代码: 1.依赖 ...

  4. 在 Linux 平台下使用 JNI

    引言 Java 的出现给大家开发带来的极大的方便.但是,如果我们有大量原有的经过广泛测试的非 Java 代码,将它们全部用 Java 来重写,恐怕会带来巨大的工作量和长期的测试:如果我们的应用中需要访 ...

  5. r.js 配置文件 example.build.js 不完整注释

    /* * This is an example build file that demonstrates how to use the build system for * require.js. * ...

  6. H5页面JS调试

    页面调试 常用的调试方法 开发时候的调试基本是在chrome的控制台Emulation完成 现有的一些手机端调试方案: Remote debugging with Opera Dragonfly 需要 ...

  7. linux系统下图片的路径

    1. 图片跟网页或者程序在同一目录下 直接 src="abc.jpg" 如果不行 就加多一个斜杠 src="/abc.jpg"

  8. Python基础(5) - 文件

    Python Python提供的函数和方法方便地对文件进行读.写.删除等的操作. open()函数返回一个文件对象. open(name[, mode[, buffering]]) -> fil ...

  9. VS快捷键设置无效

    使用Resharper 后发现有些快捷键冲突,但是在工具-选项-键盘 设置后不管用,后来发现有一个移除功能,即移走原来的快捷键; 先选择下拉框1中自己用不到的快捷键,然后移除掉; 备注: 注意观察 快 ...

  10. C# 处理XML的基本操作

    文章部分代码引用参考文章, 文末参考文章已标注 ,本篇文章建立在两篇参考文章基础上,可以先阅读参考文章 XML 相关类 XDocument XmlDocument XmlReader  XmlWrit ...