SQL CASE WHEN 用法的深度解析
备注:本文更新于2020年6月18日
前言
本文是对 SQL CASE WHEN 用法的深度解析,重新理解case when then else end用法。
在SQL的世界中CASE WHEN语句相当于if-else语句。虽然看似简单,但是CASE WHEN并不容易掌握,CASE的用法分为两种形式:简单CASE函数和CASE条件表达式函数。简单CASE函数,类似如下形式:
CASE SCORE WHEN 'A' THEN '优' ELSE '不及格' END其中,SCORE更像是CASE函数的参数,因为只能传递一个参数,所以CASE的这种用法并不灵活。简单CASE函数只能应对一些简单的业务场景,而CASE条件表达式函数的用法则更加灵活。见下面的应用场景:
CASE SCORE WHEN 'A' THEN '优' ELSE '不及格' END
CASE SCORE WHEN 'B' THEN '良' ELSE '不及格' END
CASE SCORE WHEN 'C' THEN '中' ELSE '不及格' END等同于,使用CASE条件表达式函数实现:
CASE WHEN SCORE = 'A' THEN '优'
WHEN SCORE = 'B' THEN '良'
WHEN SCORE = 'C' THEN '中'
ELSE '不及格'
END需要注意的是:THEN后边的值与ELSE后边的值类型应一致,否则会报错。如下:
CASE SCORE WHEN 'A' THEN '优' ELSE 0 END'优'和0数据类型不一致则报错:
[Err] ORA-00932: 数据类型不一致: 应为 CHAR, 但却获得 NUMBER1、CASE函数和CASE表达式函数本质都是代码块,具有返回值
在SQL中CASE函数和CASE表达式函数本质都是代码块,常用被括号括起来,如下所示:
SELECT
s.s_id,
s.s_name,
s.s_sex,
(CASE
WHEN s.s_sex = '1' THEN '男'
WHEN s.s_sex = '2' THEN '女'
ELSE '其他'
END) as sex,
s.s_age,
s.class_id
FROM
t_b_student sCASE 的常用格式是:case when then else end,这是一种表达式,在编程语言中,任何表达式都是有返回值的,SQL也不例外,可用于update更新语句,如下场景所示:现在某公司员人工资信息表如下:
| name | salary |
| 小明 | 10500 |
| 小红 | 8000 |
| 小李 | 5000 |
现在公司出台了一个奇葩的规定:
(1)对当前工资为 1 万以上的员工,降薪 10%。
(2)对当前工资低于 1 万的员工,加薪 20%。
一些人不假思索可能写出了以下的 SQL:
--条件1
UPDATE Salaries
SET salary = salary * 0.9 WHERE salary >= 10000;
--条件2
UPDATE Salaries
SET salary = salary * 1.2 WHERE salary < 10000;
这么做其实是有问题的。对小明来说,他的工资是 10500,执行第一个 SQL 后,工资变为 10500 x 0.9 = 9450,紧接着又执行条件 2,工资变为了 9450 x 1.2 = 11340,反而涨薪了!
如果用 CASE WHEN 可以解决此类问题,如下所示:
UPDATE
Salaries
SET
salary = CASE
WHEN salary >= 10000 THEN salary * 0.9
WHEN salary < 10000 THEN salary * 1.2
ELSE salary
END;2、CASE用法1:CASE函数
CASE函数的语法如下:
CASE expression
WHEN value1 THEN returnvalue1
WHEN value2 THEN returnvalue2
WHEN value3 THEN returnvalue3
ELSE defaultreturnvalue
ENDCASE函数对表达式expression进行测试,如果 expression 等于value1 则返回 returnvalue1;如果 expression 等于value2 则返回 returnvalue2,如果 expression 等于 value3 则返回 returnvalue3....以此类推,如果不符合所有的WHEN条件,则返回默认值 defaultreturnvalue。
CASE函数和普通编程语言中的 SWITCH-CASE 语句非常类似。使用CASE函数可以实现非常复杂的业务逻辑。如下所示:
select name,
(
case name
when 'tom' then 'A'
when 'adam' then 'B'
else 'C'
end
) as level
from `t_employee`3、CASE用法2:CASE条件表达式函数
上中介绍的CASE函数的用法只能用来实现简单的“等于”逻辑。如果要实现“如果年龄小于18则返回未成年人,否则返回成年人”的功能是不可能的。值得庆幸的是,CASE还提供了第二种用法,其语法如下:
CASE
WHEN condition1 THEN returnvalue1
WHEN condition2 THEN returnvalue2
WHEN condition3 THEN returnvalue3
ELSE defaultreturnvalue
END其中的condition1、condition 2、condition3为条件表达式,CASE 对这个表达式从前向后进行测试,如果条件 condition1 为真则返回 returnvalue1,否则如果条件 condition2 为真则返回 returnvalue2,否则如果条件 condition3 为真则返回returnvalue3。以此类推,如果不符合所有的 WHEN 条件,则返回默认值。
select name,
(
case
when salary < 5000 then 'low'
when salary <= 8000 then 'middle'
else 'heigh'
end
) as salary
from `t_employee`4、Java中case用法
switch case 语句语法格式如下:
switch(expression)
{
case value :
//语句
break; //可选
case value :
//语句
break; //可选
//你可以有任意数量的case语句
default : //可选
//语句
}public class Test
{
public static void main(String args[])
{
char grade = 'A';
switch (grade)
{
case 'A':
System.out.println("优秀");
break;
case 'B':
case 'C':
System.out.println("良好");
break;
case 'D':
System.out.println("及格");
break;
case 'F':
System.out.println("你需要再努力努力");
break;
default:
System.out.println("未知等级");
}
System.out.println("你的等级是 " + grade);
}
}5、如何记住SQL中的CASE的语法格式
在SQL中CASE的用处,人人都能说出一二三来,在Java中case的用法,同样的人人皆知。但是在SQL中,能熟练的使用CASE,往往人不多了。究其原因,在于CASE的语法格式很多人没有记住。可以结合Java中case的用法来记忆:
第一:SQL中的 CASE expression,相当于 Java 中的 switch(expression)
第二:SQL中的 WHEN value1 THEN returnvalue1,相当于 Java 中的 case value : statement
第三:SQL中的 ELSE defaultreturnvalue,相当于 Java 中的 default : statement