一、简介   

  官方定义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. STM32的固件升级(RTT

    STM32 通用 Bootloader ,让 OTA 更加 Easy 目前支持F1/F4,在线制作bootloader,准备固件升级,是RTT的云设备管理平台 https://mp.weixin.qq ...

  2. c# xml序列化和反序列化。也就是xml的解析和反解析。

    用习惯了newTownSoft.json 的json反序列化.碰到xml是真的不习惯. 每次json反序列化都是直接把json丢到bejson网站生成一个实体类,稍微修改修改一点点变量名.然后直接ne ...

  3. c# 短链接生成

    public static string GetShortUrl(string url) { //可以自定义生成MD5加密字符传前的混合KEY string key = DateTime.Now.To ...

  4. sencha touch 手势识别左右滑动

    sencha touch 中添加手势识别非常简单,就是监听 dom 元素的 move 事件: 1. 为你的 view 注册 swipe 事件 // 为当前 view 注册手势滑动事件 Ext.get( ...

  5. Android Gson解析复杂Json

    JSON原数据 {"total":1,"rows":[{"ID":1,"Title":"台州初级中学招收初一年 ...

  6. Mybatis基本介绍

    Mybatis介绍 1.Mybatis介绍   MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了goog ...

  7. <数据挖掘导论>读书笔记6关联分析的高级概念

    处理联系属性: 基于离散化的方法 基于统计学的方法 非离散化方法 处理概念分层 定义在一个特定领域的各种实体或者概念的多层组织.概念分层可以用有向无环图DAG来标示. 序列模式 可选计数方案 COBJ ...

  8. out参数

             out参数: 参数在方法的内部必须为其赋值:可以同时返回不同类型的值:                           在Main方法里定义,在方法里赋值:          输 ...

  9. html中块元素的居中。及兼容性

    块在块中垂直居中(父元素postion:relative;   子元素position:absolute; top:50%; margin-top:负二分之一高度) 块在块中水平居中 (子元素marg ...

  10. CORS跨域请求C#版

    1.什么是跨域请求:  当从A网站使用AJAX请求B网站时,就会出现跨域请求. 此时B网站能够接收到A网站发来的请求并返回相应的结果,但是浏览器拿到B网站返回的数据时检测到与当前网站的域名不同,出于安 ...