SQL之case表达式总结之一:构造新列并按新列汇总

一.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

猜你喜欢

转载自www.cnblogs.com/excellaotan/p/10011416.html