教你如何优雅地在MySQL中使用条件判断

MySQL中也有类似于众多程序设计语言中if,else,switch,case语句,不过它们是以函数(操作符)的形式在SQL语句中体现。
在统计任务的需求下,所需的SQL中必不可少的部分就是条件判断。本文用来记录我对于MySQL中条件判断函数的学习以及一道相关的练习题。
示例表以及数据的填充SQL语句如下:

CREATE TABLE t_test(
    age int,
    name varchar(20) not null,
    sex char(2),
    fans int
);

INSERT INTO t_test values(22, '林妙妙', '女', 666666666);
INSERT INTO t_test values(22, '钱三一', '男', 666666666);
INSERT INTO t_test values(22, '邓小琪', '女', 333333333);
INSERT INTO t_test values(22, '江天昊', '男', 333333333);
INSERT INTO t_test values(NULL, '王胜男', '女', 333333333);
INSERT INTO t_test values(NULL, '大为哥', NULL, 333333333);

填充后的数据如下图所示:
image.png

CASE

官方文档中CASE语句的格式如下:

-- 返回值为when条件中第一个等于value的结果,如果没有相等的,则返回else子句后面的
-- 结果。没有else子句将返回NULL
CASE value
    when value1 then result1
    when value2 then result2
    ....
    else result_else
END

-- 返回值为when后面第一个值为true的条件语句所对应的结果。如果条件语句都为false,则返回
-- else语句后的结果。没有else子句则返回NULL
CASE
  when 条件语句1 then result1
  when 条件语句2 then result2
  ....
  else result_else
END

-- 切记不要忘记END为结束符

实例:查找每个人物的年龄,如果她的年龄为空,则返回该角色年龄信息未知的消息,否则返回真实年龄。

SELECT name, CASE
when age is null then '年龄消息未知'
when age = 22 then sex
else age
end as age
from t_test;

注意:case语句的返回值类型为then语句后面返回值的一个聚合,本例返回值age的数据类型为varchar(11)。
image.png

IF

IF (expr1, expr2, expr3)
如果表达式expr1值为true,或者expr1不等于0且不为NULL,则返回expr2的值,否则返回expr3的值。

  • 如果expr2或者expr3中任意一个表达式产生的值为字符串,则IF的返回值类型为字符串
  • 如果expr2或者expr3产生的值都为字符串,只要其中一个字符串是区分大小写的,则IF的返回值也是区分大小写的

实例:查找t_test表中有多少人的性别是已知的

SELECT SUM(IF(sex is null, 0, 1)) as sex_known_persons
from t_test;

image
除了大为哥之外,其余5人性别皆是已知的,因此结果是5。这也是条件函数与聚合函数的联合使用示例。

IFNULL

IFNULL(expr1, expr2)
如果表达式expr1不为NULL,则返回expr1,否则返回expr2。
同样IFNULL的返回值是expr1表达式和expr2表达式中更为通用的一个。String > Real > Integer。
下面所示代码与CASE示例中的代码效果一致:

SELECT name, IFNULL(age, '年龄消息未知') as age
from t_test;

实操:LeetCode608.树节点

https://leetcode.cn/problems/tree-node/
给定一个表tree,id是树节点的编号,p_id是父节点的id。

+----+------+
| id | p_id |
+----+------+
| 1  | null |
| 2  | 1    |
| 3  | 1    |
| 4  | 2    |
| 5  | 2    |
+----+------+

给吃一个查询语句,输出每个id对应的树节点在树中所属于的节点类型。根节点类型为'Root',内部节点为'Inner', 叶子节点为'Leaf'。该查询语句用于上面的例表将返回下图的结果表。

+----+------+
| id | Type |
+----+------+
| 1  | Root |
| 2  | Inner|
| 3  | Leaf |
| 4  | Leaf |
| 5  | Leaf |
+----+------+

思路:

  • 遍历tree表中的每一节点(id)
  • 对于当前遍历到的树节点,若它的pid为NULL,则它为根节点。否则,我们再次遍历整张tree表,计算以该节点的id为p_id的节点有多少个,若为0个,则它为叶节点,否则它为中间节点
  • 对于当前每一个遍历到的树节点id,我们都要再次根据整个表与该节点进行比对,然后将结果输出到结果表中。因此很容易想到需要用标量子查询进行这个比对输出的过程,同时比对过程中有两次,若,则,否则的情况,这是明显的条件判断,因此需要使用条件判断语句。
# Write your MySQL query statement below
select t1.id, case 
when t1.p_id is null then 'Root' 
else 
  case 
  when (select count(t2.id) from tree as t2 where t2.p_id = t1.id) = 0 then 'Leaf' 
  else 'Inner' 
  end 
end as type
from tree as t1;
select t1.id, if (t1.p_id is null, 'Root',
case
     when (select count(t2.id) from tree as t2 where t2.p_id = t1.id) = 0 then 'Leaf'
     else 'Inner'
end
) as type
from tree as t1;

参考链接:官方文档
官方文档讲的很详细,但是英文的,里面还讲了一些关于值数据类型的细节。待碰到时再慢慢分析吧。

如果感觉本文对你有所帮助的话,麻烦给笔者一个三连,你的支持是我前进的动力。一起加油!!!

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZW钟文

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值