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# 复制数组容易踩到的坑--引用类型与值类型

    原文链接:https://my.oschina.net/u/3744313/blog/1794235 笔者近期做的项目里大量使用了数组,而在使用过程中,笔者曾经遇到了一个比较低级的问题:如何将一个数组 ...

  2. mysql排序字段为空的排在最后面

    排序字段为orderid; 1.使用order by orderid desc实现降序时,orderid 为null数据的会排在数据的最后面: 但是,order by orderid升序时,order ...

  3. Docker部署OpenProject

    效果如下: 部署教程: 下载镜像: docker pull openproject/community: Install OpenProject with Docker Docker is a way ...

  4. AndoridSQLite数据库开发基础教程(8)

    AndoridSQLite数据库开发基础教程(8) 添加索引 索引是一种通过预先排序和对表的一个或多个列构建索引表来优化数据库查找的手段.下面为表添加索引,操作步骤如下: (1)在打开的数据库中,单击 ...

  5. 【转】Django继承AbstractUser新建User Model时出现auth.User.groups: (fields.E304)错误

    错误详情如下: (venv) D:\workspace\music>python manage.py makemigrations SystemCheckError: System check ...

  6. 0.9.0.RELEASE版本的spring cloud alibaba nacos+gateway网关实例

    gateway就是用来替换zuul的,功能都差不多,我们看下它怎么来跟nacos一起玩.老套路,三板斧: 1.pom: <?xml version="1.0" encodin ...

  7. Spring cloud微服务安全实战-3-6API安全机制之数据校验

    校验:非空.唯一性等校验 密码的加密:密码加密来存储. 如何做https的访问 校验 一个层面是接口层面,另外一个层面是数据库层面. Springboot给我们提供了简单的封装 校验的包里面还有其他的 ...

  8. DDos攻击解决办法

    (1).DDos概念 分布式拒绝服务攻击(英文意思是Distributed Denial of Service,简称DDoS)是指处于不同位置的多个攻击者同时向一个或数个目标发动攻击,或者一个攻击者控 ...

  9. c# 子线程与主线程通信二

    之前写过使用线程上下文实现线程同步,今天利用子线程向主线程发送事件,实现子线程与主线程的同步 基本步骤 1.定义类 using System; using System.Collections.Gen ...

  10. Java Audio : Playing PCM amplitude Array

    转载自:http://ganeshtiwaridotcomdotnp.blogspot.com/2011/12/java-audio-playing-pcm-amplitude-array.html ...