一.case表达式概述:
case表达式有简单case表达式(simple case expression)和搜索case表达式(searched case expression).case表达式是一个标量表达式,返回一个基于条件的逻辑值,千万注意:case表达式不是一个编程的分支语句,它不能控制程序流.两种表达式的语法如下:
--简单case表达式语法
case gender when 1 then '男' when 0 then '女' else 'uk' end
--搜索case表达式 case when gender = 1 then '男' when gender = 0 then '女' else 'uk' end
简单case表达式写法简单,能实现的功能也很少,简单case表达式能写的条件,搜索case表达式也能写,所以这里主要介绍搜索case表达式.
在case表达式里,还可以使用between,like,和比较运算符等,还能嵌套子查询的in和exists谓词,因此,case表达式具有非常强的表达能力.
二.使用case表达式需要注意的事项
1.各分支返回数据类型的一致性
2.end关键写是与case关键字配对的,不能省略
3.养成写else子句的习惯
三.实例演练
[应用]:根据已有字段来构造新字段,并按新构造的字段统计数据:
[实例一]:现有这样一个样本表,要求按照各省份对应的区域来按性别汇总人口数量
在select 语句中构造一个新字段[区域]
汇总后效果:
代码演练如下:
--第一步:在demo数据库中创建一张数据表 test------------------------------------------------------------------------------------- use demo go if OBJECT_ID('test') is not null drop table test go create table test ( province nvarchar(50), city nvarchar(50), town nvarchar(50), area decimal(18,2), shot nvarchar(50), gender int, person decimal(18,2) ) go --第二步:利用bulk insert语句把excel表整体导入至数据表 test----------------------------------------------------------------------- bulk insert test from 'E:\Thb\个人课件\0_Files\行政区人口test.csv' with ( fieldterminator=',', rowterminator='\n', firstrow=2 ) go --第三步:创建一个cte,用于存放中间结果,使代码更具有阅读性--------------------------------------------------------- with temp as ( SELECT CASE WHEN province IN('黑龙江省','吉林省','辽宁省') then '东北地区' WHEN province IN('北京市','天津市','河北省','山西省','内蒙古自治区') then '华北地区' WHEN province IN('河南省','湖北省','湖南省') then '华中地区' WHEN province IN('山东省','江苏省','安徽省','上海市','浙江省','江西省','福建省','台湾省') then '华东地区' WHEN province IN('广东省','广西壮族自治区','海南省','香港特别行政区','澳门特别行政区') then '华南地区' WHEN province IN('陕西省','甘肃省','宁夏回族自治区','青海省','新疆维吾尔自治区') then '西北地区' WHEN province IN('四川省','贵州省','云南省','重庆市','西藏自治区') then '西南地区' ELSE 'UK' END AS 区域,province,city,town,area,shot,gender,person from test ) --第四步:最终sql语句------------------------------------------------------------------------------------------ SELECT 区域, sum(CASE WHEN gender=1 then person else 0 end) as '男性人口', SUM(CASE WHEN gender=0 then person else 0 end) as '女性人口' FROM temp GROUP BY 区域 UNION ALL SELECT '合计', sum(CASE WHEN gender=1 then person else 0 end), SUM(CASE WHEN gender=0 then person else 0 end) FROM temp
[实例二],接上例,根据省份的面积来划分等级[>1000000为特大面积省份,>500000为大面积省份,>200000为中等面积省份,>100000为小面积省份,<=100000为特小面积省份]
最终结果:
代码演练如下:
--第一步:创建CTE命名为t,使得后续代码阅读起来更加方便直观; with t as ( SELECT province,SUM(distinct area) as 面积, case when SUM(distinct area)>1000000 then '特大面积省份' when SUM(distinct area)>500000 then '大面积省份' when SUM(distinct area)>200000 then '中等面积省份' when SUM(distinct area)>100000 then '小面积省份' else '特小面积省份' end as 等级 from test group by province UNION ALL SELECT '合计',SUM(distinct area),'--' from test ) --第二步:利用case语句处理排序的结果 SELECT * FROM t order by case when province = '合计' then 9 --虚构了一个排序键 else 0 end asc, 面积 desc
[应用二]在case语句中使用子查询的in和exists谓词
[实例三]现有一张课程表和一张开课表,如下图示,
现要求根据开课表,生成一张更加直观的开课表,如下图示
演练代码如下:
--第一步:创建数据库并插入测试数据:-------------------------------------------------------------------------- USE demo GO --创建课程表 IF EXISTS(SELECT * FROM SYS.objects WHERE name='课程表') DROP TABLE 课程表 GO CREATE TABLE 课程表 ( 课程ID int, 课程 nvarchar(20) ) GO --创建开课表 IF OBJECT_ID('开课表') IS NOT NULL DROP TABLE 开课表 GO CREATE TABLE 开课表 ( 年月 int, 课程ID int ) GO --插入测试数据 INSERT INTO 课程表(课程ID,课程) VALUES(1,'Excl VBA'),(2,'Python入门'),(3,'SQl经典'),(4,'Access进阶') INSERT INTO 开课表(年月,课程ID) VALUES(200706,1),(200706,3),(200706,4),(200707,4),(200708,2),(200708,4) GO --第二步:在case语句中嵌入子查询谓词来求解最后结果----------------------------------------------------------- SELECT 课程, CASE WHEN 课程ID IN(SELECT 课程ID FROM 开课表 WHERE 年月 = 200706) THEN '√' ELSE '×' END AS '六月', CASE WHEN 课程ID IN(SELECT 课程ID FROM 开课表 WHERE 年月 = 200707) THEN '√' ELSE '×' END AS '七月', CASE WHEN 课程ID IN(SELECT 课程ID FROM 开课表 WHERE 年月 = 200708) THEN '√' ELSE '×' END AS '八月' FROM 课程表 --或利用exists谓词来求解 SELECT 课程, CASE WHEN EXISTS(SELECT * FROM 开课表 WHERE 课程ID=a.课程ID AND 年月=200706) THEN '√' ELSE '×' END AS '六月', CASE WHEN EXISTS(SELECT * FROM 开课表 WHERE 课程ID=a.课程ID AND 年月=200707) THEN '√' ELSE '×' END AS '七月', CASE WHEN EXISTS(SELECT * FROM 开课表 WHERE 课程ID=a.课程ID AND 年月=200708) THEN '√' ELSE '×' END AS '八月' FROM 课程表 AS a