1-1 case表达式-SQL进阶教程

case表达式概述

case表达式的写法

-- 简单case表达式
case sex
	when '1' then '男'
	when '2' then '女'
	else '其他'
end	

-- 搜索case表达式
case when sex='1' then '男'
	when sex='2' then '女'
 	else '其他'
end

剩余的when子句被忽略的写法示例

-- 例如, 这样写的话, 结果里不会出现 "第二"
case when col_1 in('a','b') then '第一'
	when col_2 in('a') then '第二'
	else '其他'
end

注意事项 1:统一各分支返回的数据类型
注意事项 2:不要忘了写END
注意事项 3:养成写ELSE子句的习惯

将已有编号方式转换为新的方式并统计

在这里插入图片描述

-- 把县编号转换成地区编号
select 
case pref_name
	when '德岛' then '四国'
	when '香川' then '四国'
	when '爱媛' then '四国'
	when '高知' then '四国'
	when '福冈' then '九州'
	when '左贺' then '九州'
	when '长崎' then '九州'
	else '其他'
end 
as district,
sum(population)
from PopTbl
group by 
case pref_name
	when '德岛' then '四国'
	when '香川' then '四国'
	when '爱媛' then '四国'
	when '高知' then '四国'
	when '福冈' then '九州'
	when '左贺' then '九州'
	when '长崎' then '九州'
	else '其他'
end;

-- 按人口数量等级划分都道府县
select
case 
	when population<100 then '01'
	when population>=100 and population<200 then '02'
	when population>=200 and population<300 then '03'
	when population>300 then '04'
	else null
end
as pop_class,
count(*) as cnt
from PopTbl
group by
case 
	when population<100 then '01'
	when population>=100 and population<200 then '02'
	when population>=200 and population<300 then '03'
	when population>300 then '04'
	else null
end;

-- 把县编号转换成地区编号: 将case表达式归纳到一处
select 
case pref_name
	when '德岛' then '四国'
	when '香川' then '四国'
	when '爱媛' then '四国'
	when '高知' then '四国'
	when '福冈' then '九州'
	when '左贺' then '九州'
	when '长崎' then '九州'
	else '其他'
end 
as district,
sum(population)
from PopTbl
group by district;	-- group by子句里引用了select子句中定义的别名
/*
严格来说,这种写法是违反标准SQL的规则的。因为GROUP BY子句比SELECT语句先执行
但在PostgreSQL和MySQL中,这个查询语句可以顺利执行
*/

用一条SQL语句进行不同条件的统计

在这里插入图片描述

select pref_name,
-- 男性人口
sum(
	case
		when sex='1' then population
		else 0
	end
) as cnt_m,
-- 女性人口
sum(
	case
		when sex='2' then population
		else 0	
	end
) as cnt_f
from PopTbl2
group by pref_name;

用check约束定义多个列的条件关系

-- 蕴含式: 如果是女性员工,则工资是20万日元以下
constraint check_salary check(
	case
		when sex='2' then
			case
				when salary<=200000 then 1
				else 0
			end
		else 1
		end=1
)
/*
要想让蕴含式P→Q为真,需要命题P和命题Q均为真,或者P为假,或者P无法判定真假
如果不满足“是女性”这个前提条件,则无需考虑工资约束
*/

-- 逻辑与: 该公司将不能雇佣男性员工
constraint check_salary check(
	sex='2' and salary<=200000
)
/*
要想让逻辑与P∧Q为真,需要命题P和命题Q均为真,或者一个为真且另一个无法判定真假
能在这家公司工作的是“性别为女且工资在20万日元以下”的员工,以及性别或者工资无法确定的员工
*/

在这里插入图片描述

在update语句里进行条件分支

在这里插入图片描述

update Salaries
set salary=
	case
		when salary>=300000
		then salary*0.9
		when salary>=250000 and salary<280000
  		then salary*1.2
  		else salary
  	end;	

在这里插入图片描述

-- 用case表达式调换主键值
update SomeTable
set p_key=
	case
		when p_key='a'
		then 'b'
		when p_key='b'
		then 'a'
		else p_key
	end
where p_key in('a','b');

表之间的数据匹配

在这里插入图片描述
在这里插入图片描述

-- 表的匹配:使用in谓词
select course_name,
case
	when course_id in(
	select course_id
	from OpenCourses
	where month=200706
	)
	then '○'
	else '×'
end
as '6月',
case
	when course_id in(
	select course_id
	from OpenCourses
	where month=200707
	)
	then '○'
	else '×'
end
as '7月',
case
	when course_id in(
	select couse_id
	from OpenCouses
	where month=200708
	)
	then '○'
	else '×'
end
as '8月'
from CourseMaster;

-- 表的匹配:使用exist谓词
select CM.course_id,
case
	when exists(
	select couse_id
	from OpenCourses OC
	where month=200706
	and OC.course_id=CM.course_id
	)
	then '○'
	else '×'
end
as '6月',
case
	when exists(
	select course_id
	from OpenCourses OC
	where month=200707
	and OC.course_id=CM.course_id
	)
	then '○'
 else '×'
end
as '7月',
case
	when exists(
	select course_id
	from OpenCourses
	where month=200708
	and OC.course_id=CM.course_id
 )
	then '○'
 	else '×'
end
as '8月'
from CouseMaster CM;
/*
无论使用IN还是EXISTS,得到的结果是一样的,但从性能方面来说,EXISTS更好
通过EXISTS进行的子查询能够用到“month, course_id ”这样的主键索引,因此尤其是当表OpenCourses里数据比较多的时候更有优势
*/

在case表达式中使用聚合函数

在这里插入图片描述

select std_id,
case
	when count(*)=1  -- 选择只加入一个社团的学生
	then max(club_id)
	else max( -- 选择加入了多个社团的学生
		case
			when main_club_flg='Y'
			then club_id
			else null
		end
	)
end
as main_club
from StudentClub
group by std_id;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值