sql中的case when 有点类似于Java中的switch语句,比较灵活,但是在Mysql中对于Null的处理有点特殊

Mysql中case when语法:

语法1:

CASE case_value
WHEN when_value THEN statement_list
[WHEN when_value THEN statement_list] ...
[ELSE statement_list]
END CASE

  

语法2:

CASE
WHEN search_condition THEN statement_list
[WHEN search_condition THEN statement_list] ...
[ELSE statement_list]
END CASE

  

注意:  这两种语法是有区别的,区别如下:

1:第一种语法:case_value必须是一个表达式,例如 userid%2=1或者username is null等。该种语法不能用于测试NULL。

2:第二种语法CASE后面不需要变量或者表达式,直接执行时候评估每一个WHEN后面的条件,如果满足则执行。

案例实战:

表结构如下:a 值为null, b值为1

mysql> SELECT NULL AS a, 1 AS b;
+------+---+
| a   | b |
+------+---+
| NULL | 1 |
+------+---+

  

现在实现,如果a值为null 则取b值,否则取a值

方法1: ifnull 用法

SELECT
IFNULL(a, b) AS new,
a,
b
FROM
-- 创建临时表: a 的值为null ,b为1
(SELECT NULL AS a, 1 AS b) tmp;

  

方法2: case when 用法

SELECT
(
CASE a
WHEN a IS NULL THEN
b
ELSE
a
END
) AS new,
a,
b
FROM
(SELECT NULL AS a, 1 AS b) tmp;

  

发现得到的结果不对,new 的值居然为null ,而不是我们想要的1.

为什么会出现这个错误呢?是将第一种语法与第二种语法混用导致的,case 后面commission_pct 的值有两种:真实值或者为null,而 when 后面的commission_pct is null 也有两个值:true或者false,所以case 后面为null时候永远无法跟true或false匹配,因此输出不为null。

对于该种情况如果必须要用语法1的话可以如下改写:

SELECT
(
CASE a IS NULL
WHEN TRUE THEN b
ELSE a
END
) AS new,
a,
b
FROM
(SELECT NULL AS a, 1 AS b) tmp;

  

也可以使用语法2写:

SELECT
(
CASE
WHEN a is NULL THEN b
ELSE a
END
) AS new,
a,
b
FROM
(SELECT NULL AS a, 1 AS b) tmp;

  

注意另一种可能存在错误却不容易发现错误的情况:

SELECT
(
CASE a
WHEN NULL THEN b
ELSE a
END
) AS new,
a,
b
FROM
(SELECT NULL AS a, 1 AS b) tmp;

  

看似没有问题,实际有问题,问题原因就是null的判断不能用=进行判断。简单说就是:语法1中的case表达式的值与后面的when的值使用的=进行判等,但是mysql中必须使用is 或者is not。

总结:

1:语法1是将case后面的表达式值计算好之后跟后面的when条件的值使用“=”进行判断相等,相等就进入该分支。

2:语法2是不需要case后面有表达式,直接评估when后面的条件值即可,如果为true则进入。

MySQL中的case when 中对于NULL值判断的坑的更多相关文章

  1. 在switch中的case语句中声明变量编译出错的解决方案

    在switch中的case语句中声明变量编译的问题 先来看段代码,别管什么意思: : , j = ; ; i < ; i++) recive_phone[i] = msgbuf.text[i]; ...

  2. C#中烦人的Null值判断竟然这样就被消灭了

    作者:依乐祝 首发自:DotNetCore实战 公众号 https://www.cnblogs.com/yilezhu/p/14177595.html Null值检查应该算是开发中最常见且烦人的工作了 ...

  3. 在switch中的case语句中声明变量会被提前

    原文链接:http://my.oschina.net/u/2000201/blog/514384 本人今天在编写工具类时,无意之间发现,在Java的Swith语句的case语句中声明局部变量时出现了一 ...

  4. 【hive】null值判断

    hive用作null值的判断是不能用 = , != 来判断的 只能用is [not] null来完成 不支持ifnull()函数(mysql支持) 适用于所有数据类型 (1)条件中判断是否为空 whe ...

  5. SQLSERVER NULL值判断

    sqlserver 在判断数据条件时,如果数据包含null的话则永远为false,null不参与判断,可以使用isnull(列,默认值)来判断null值的数据列,或者列 is null or 列的条件 ...

  6. 输入框中的空"",0,null的判断

    改了一个小项目,里面有一个小的问题他们是这样提需求的.两个输入框,第一个输入框里面,输入的内容会对第二个输入框中的内容产生影响.具体是这样的:如果第一个输入框中的值不是“0”,那么第二个输入框就不能填 ...

  7. java中List<Map<String, Object>>关于null的判断

    List<Map<String, Object>> selectTmFileInfo = fileInfoService.selectTmFileInfoByToken(cTo ...

  8. 通过kettle数据导入mysql时,空值的处理在插入mysql时,会自动转转换为null值,无法插入

    1.windows下C:\Users\用户名\.kettle目录中找到kettle.properties文件,增加KETTLE_EMPTY_STRING_DIFFERS_FROM_NULL=Y2.Li ...

  9. 为什么说JAVA中要慎重使用继承 C# 语言历史版本特性(C# 1.0到C# 8.0汇总) SQL Server事务 事务日志 SQL Server 锁详解 软件架构之 23种设计模式 Oracle与Sqlserver:Order by NULL值介绍 asp.net MVC漏油配置总结

    为什么说JAVA中要慎重使用继承   这篇文章的主题并非鼓励不使用继承,而是仅从使用继承带来的问题出发,讨论继承机制不太好的地方,从而在使用时慎重选择,避开可能遇到的坑. JAVA中使用到继承就会有两 ...

随机推荐

  1. C图形化第一步

    之前的贪吃蛇都是在cmd下实现,每次都要调用cls刷新屏幕,简直是闪瞎了我的狗眼. 度娘得知有一种方法可以避免闪烁,即:双缓冲.原理是先在内存中作图,然后将做好的图复制到前台,同时禁止背景刷新. 主要 ...

  2. package.json 字段说明

    以vue的package.json为例: { // 名称 "name": "vue", // 版本 "version": "2.6 ...

  3. HTTPWebrequest上传文件--Upload files with HTTPWebrequest (multipart/form-data)

    使用HTTPWebrequest上传文件遇到问题,可以参考Upload files with HTTPWebrequest (multipart/form-data)来解决 https://stack ...

  4. Django HttpResponse与JsonResponse

    本文链接:https://blog.csdn.net/mr_hui_/article/details/86498509 我们编写一些接口函数的时候,经常需要给调用者返回json格式的数据,那么如何返回 ...

  5. REDIS中加锁和解锁问题

    使用lua+redis的方法.之所以使用lua是为了保证原子性 问题: 1. redis发现锁失败了要怎么办?中断请求还是循环请求?2. 循环请求的话,如果有一个获取了锁,其它的在去获取锁的时候,是不 ...

  6. Data Governance Solution

    如何有效地进行数据治理 | 人人都是产品经理http://www.woshipm.com/data-analysis/746223.html ##普元元数据管理(MetaCube)产品-白皮书.doc ...

  7. Composer 安装 Jira API 库

    环境要求: PHP >= 5.5.9 php JsonMapper phpdotenv 安装 下载安装 Composer curl -sS https://getcomposer.org/ins ...

  8. Vue 及双向数据绑定 Vue事件 以及Vue中的ref获取dom节点

    <template> <div id="app"> <h2>{{msg}}</h2> <input type="te ...

  9. k8s之磁盘挂载持久化

  10. nginx 开启rewrite_log日志