SQL——case的用法

本文详细介绍了SQL中CASE WHEN语句的使用,包括如何进行条件判断和行转列操作。通过示例展示了如何利用CASE WHEN结合GROUP_CONCAT将课程表数据按天和时间段转换为所需格式。此外,还提到了行列转置的另一种方法——PIVOT,及其在SQLServer2000中的实现方式。内容深入浅出,适合SQL初学者和进阶者学习。
摘要由CSDN通过智能技术生成

case when

case when 用于计算条件列表的表达式,并返回条件对应的结果。通俗一点讲就是“如果……就……”。

语法:

case 
when condition_1 then result_1
when condition_2 then result_2
…
else result_n
end

注意事项:

  • 在sql中如果需要进行如“如果……就……”的逻辑判断,最好使用case when;
  • 条件大于等于1即可;
  • else 根据需求决定,可有可无;
  • 如果满足了condition_1,会返回result_1,不会考虑后面的条件,即若后面又满足condition_2,并不会返回result_2,这是逻辑判断的先入为主原则;
  • 最后结束语“end”不可省略。

例如:
当 sex=‘1’ 时,性别为‘男’;当 sex=‘0’ 时,性别为‘女’;

case 
when sex='1' then '男'
when sex='0' then '女'
else '其他'		# else 可有可无
end
as '性别';	# 新的列名为‘性别’

当 sex=‘1’ 且 age>‘18’ 时,年龄段为‘成年男性’;
当 sex=‘1’ 且 ‘7’<age<‘18’ 时,年龄段为‘未成年男性’;
当 sex=‘0’ 且 age>‘18’ 时,年龄段为‘成年女性’;
当 sex=‘0’ 且 ‘7’<age<‘18’ 时,年龄段为‘未成年女性’;
当 age<‘7’ 时,年龄段为‘婴幼儿’;

select name,
case 
when sex='1' and age>18 then '成年男性'
when sex='1' and age>7 then '未成年男性' 	# 根据逻辑判断先入为主,省略判断 'age<18'
when sex='0' and age>18 then '成年女性'
when sex='0' and age>7 then '未成年女性'
else '婴幼儿'
end
as '年龄段'	# 新的列名为‘年龄段’
from Preson;

case 行转列

case 用的比较广泛的功能就是行转列,就是将记录行里的数据按条件转换成具体的列。

现有如下例子:
例子来源点击此处(为了自己思考SQL语句,对视频中表数据和参数等做了修改)

已有一个课程详细记录表,现需要通过sql查询整理出一周内每天的课程表。

输入:

iddaycourse_namemorningafternoon
1周一语文有课有课
2周一数学null有课
3周三语文有课null
4周四数学null有课
5周四英语有课null
6周五英语有课null

输出:

time周一周二周三周四周五
上午语文无课语文英语英语
下午语文,数学无课无课数学无课

SQL语句如下:

# 创建表
create table course(
id int,
day varchar(20) not null default '',
course_name varchar(20) not null,
morning varchar(20),
afternoon varchar(20),
primary key('id')
);

# 插入表数据
insert into course values(1,'周一','语文','有课','有课')insert into course values(2,'周一','数学',null,'有课')insert into course values(3,'周三','语文','有课',null)insert into course values(4,'周四','数学',null,'有课')insert into course values(5,'周四','英语','有课',null)insert into course values(6,'周五','英语','有课',null)# 查询
select time,
ifnull(group_concat(case when day='周一' and ifyouke='有课' then course_name else null end),'无课') '周一',
ifnull(group_concat(case when day='周二' and ifyouke='有课' then course_name else null end),'无课') '周二',
ifnull(group_concat(case when day='周三' and ifyouke='有课' then course_name else null end),'无课') '周三',
ifnull(group_concat(case when day='周四' and ifyouke='有课' then course_name else null end),'无课') '周四',
ifnull(group_concat(case when day='周五' and ifyouke='有课' then course_name else null end),'无课') '周五',
from
(
select day,course_name,morning as ifyouke,'上午' as time 
from course
union all
select day,course_name,afternoon as ifyouke,'下午' as time 
from course
) as t
group by time;

查询语句思路解读:

  1. 将course表拆分出上午有课情况和下午有课情况,得到 t
select day,course_name,morning as ifyouke,'上午' as time 
from course
union all
select day,course_name,afternoon as ifyouke,'下午' as time
from course

上面的sql语句执行结果如下图:

在这里插入图片描述

  1. 按 “上午” 和 “下午” 分组查询每天的有课情况

首先对 t 表按 “time” 进行分组,通过 case when 按 “day” 和 “ifyouke” 选取有课的记录,但是这样查询的结果如下:

select time,
case when day='周一' and ifyouke='有课' then course_name else null end as '周一'  # as可省略
from t
group by time;

在这里插入图片描述
从上图可以看到周一下午有语文和数学,两条记录是分开的,而实际上希望得到的是语文和数学合并在一条记录

所以接下来需要引入 group_concat 函数,将同一个分组的字段连接起来,返回一个字符串结果。
group_concat用法

select time,
group_concat(case when day='周一' and ifyouke='有课' then course_name else null end) '周一'   
from t
group by time;

在这里插入图片描述
最后通过 ifnull 函数将没有课程安排的时间设置为“无课”,例如周三下午没有课程安排,按上述语句会返回结果“null”(如下面左图),加上 ifnull 函数后返回结果如下面右图:

select time,
ifnull(group_concat(case when day='周三' and ifyouke='有课' then course_name else null end),'无课') '周三'
from t
group by time;

在这里插入图片描述

  1. 经过上述查询就可以得到一天的有课情况,之后就是复制粘贴 ifnull(group_concat(case when…),…) 依次得到每天的有课情况,结果如下:
select time,
ifnull(group_concat(case when day='周一' and ifyouke='有课' then course_name else null end),'无课') '周一',
ifnull(group_concat(case when day='周二' and ifyouke='有课' then course_name else null end),'无课') '周二',
ifnull(group_concat(case when day='周三' and ifyouke='有课' then course_name else null end),'无课') '周三',
ifnull(group_concat(case when day='周四' and ifyouke='有课' then course_name else null end),'无课') '周四',
ifnull(group_concat(case when day='周五' and ifyouke='有课' then course_name else null end),'无课') '周五',
from t
group by time;

在这里插入图片描述

行列转置新方法——PIVOT

PIVOT用于将列值旋转为列名(即行转列),在SQL Server 2000可以用聚合函数配合CASE语句实现

PIVOT的一般语法是:PIVOT(聚合函数(列) FOR 列 in (…) )AS P

table_source
PIVOT(
聚合函数(value_column)
FOR pivot_column
IN(<column_list>)
)

UNPIVOT用于将列明转为列值(即列转行),在SQL Server 2000可以用UNION来实现

table_source
UNPIVOT(
value_column
FOR pivot_column
IN(<column_list>)
)

关于pivot的详细讲解点击进入

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值