一、简介   

  官方定义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. selenium 多窗口(windows)及ITargetLocator使用总结

    1. selenium能实现窗口切换的原理 2. 常见命令 2.1 WindowHandle 2.2 WindowHandles 2.3 SwitchTo 3. 使用JavaScript新建窗口 4. ...

  2. DP Intro - poj 1947 Rebuilding Roads

    算法: dp[i][j]表示以i为根的子树要变成有j个节点的状态需要减掉的边数. 考虑状态转移的时候不考虑i的父亲节点,就当不存在.最后统计最少减去边数的 时候+1. 考虑一个节点时,有两种选择,要么 ...

  3. Unity QualitySettings.shadows 阴影

    QualitySettings.shadows 阴影 public static ShadowQuality shadows; Description 描述: 要使用的实时阴影类型. 这就决定了应该使 ...

  4. C#中动态调用DLL动态链接库(转)

    本来是想实现控制台程序运行时自动全屏,但是只找到VC下的实现方法(http://www.vckbase.com/bbs/prime/viewprime.asp?id=347). 其中要使用两个未公开的 ...

  5. MySQL表级约束和列级约束

    对一个数据列建立的约束,称为列级约束 对多个数据列建立的约束,称为表级约束 列级约束即可以在列定义时生命,也可以在列定义后声明. 表级约束只能在列定义后声明. NOT NULL和DEFAULT只存在列 ...

  6. Vi/Vim命令壁纸图

    下载地址 http://pan.baidu.com/s/1mtQdY

  7. goLang冒泡

    // test project main.gopackage main import (    "fmt") func main() {    var a = [10]int{1, ...

  8. MySQL通过SQL语句来直接生成新表

    1. 既复制表结构,也复制表数据 mysql> CREATE TABLE tmp_table SELECT * FROM dede_news; 说明:这种方法的缺点就是新表中没有了旧表的prim ...

  9. Django 入门项目案例开发(下)——创建项目应用及模型类

    关注微信公众号:FocusBI 查看更多文章:加QQ群:808774277 获取学习资料和一起探讨问题. 前面两章是在已经开发好的项目上用来描述环境和业务,这一章创建一个全新的项目来用作开发,你可以跟 ...

  10. Redis云端架构深入浅出

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由腾讯云数据库 TencentDB 发表于云+社区专栏 作者介绍:邹鹏,腾讯云数据库Redis产品负责人,多年数据库.网络安全研发经验. ...