MySQL中的case when 中对于NULL值判断的坑
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值判断的坑的更多相关文章
- 在switch中的case语句中声明变量编译出错的解决方案
在switch中的case语句中声明变量编译的问题 先来看段代码,别管什么意思: : , j = ; ; i < ; i++) recive_phone[i] = msgbuf.text[i]; ...
- C#中烦人的Null值判断竟然这样就被消灭了
作者:依乐祝 首发自:DotNetCore实战 公众号 https://www.cnblogs.com/yilezhu/p/14177595.html Null值检查应该算是开发中最常见且烦人的工作了 ...
- 在switch中的case语句中声明变量会被提前
原文链接:http://my.oschina.net/u/2000201/blog/514384 本人今天在编写工具类时,无意之间发现,在Java的Swith语句的case语句中声明局部变量时出现了一 ...
- 【hive】null值判断
hive用作null值的判断是不能用 = , != 来判断的 只能用is [not] null来完成 不支持ifnull()函数(mysql支持) 适用于所有数据类型 (1)条件中判断是否为空 whe ...
- SQLSERVER NULL值判断
sqlserver 在判断数据条件时,如果数据包含null的话则永远为false,null不参与判断,可以使用isnull(列,默认值)来判断null值的数据列,或者列 is null or 列的条件 ...
- 输入框中的空"",0,null的判断
改了一个小项目,里面有一个小的问题他们是这样提需求的.两个输入框,第一个输入框里面,输入的内容会对第二个输入框中的内容产生影响.具体是这样的:如果第一个输入框中的值不是“0”,那么第二个输入框就不能填 ...
- java中List<Map<String, Object>>关于null的判断
List<Map<String, Object>> selectTmFileInfo = fileInfoService.selectTmFileInfoByToken(cTo ...
- 通过kettle数据导入mysql时,空值的处理在插入mysql时,会自动转转换为null值,无法插入
1.windows下C:\Users\用户名\.kettle目录中找到kettle.properties文件,增加KETTLE_EMPTY_STRING_DIFFERS_FROM_NULL=Y2.Li ...
- 为什么说JAVA中要慎重使用继承 C# 语言历史版本特性(C# 1.0到C# 8.0汇总) SQL Server事务 事务日志 SQL Server 锁详解 软件架构之 23种设计模式 Oracle与Sqlserver:Order by NULL值介绍 asp.net MVC漏油配置总结
为什么说JAVA中要慎重使用继承 这篇文章的主题并非鼓励不使用继承,而是仅从使用继承带来的问题出发,讨论继承机制不太好的地方,从而在使用时慎重选择,避开可能遇到的坑. JAVA中使用到继承就会有两 ...
随机推荐
- Ubuntu 18.04.1 安装java8
###下载tar.gz 点击选择接收协议 下载完文件之后,将文件从Windows复制到ubuntu上,可以用xShell,putty,git.这里用git 下载安装git之后,再任意位置右击,选择 g ...
- Fiddler查看request是由哪一个process发起的
有一个Process列 查看到进程编号是24836 然后用chrome自带的TaskManager查看对应的是哪一个进程 https://www.lifewire.com/google-chrome- ...
- 7年.NET面试Java的尴尬历程
先简单介绍LZ 现如今的情况,LZ 1992年出生,2012年实习,大专学渣一枚,实习期直接被校企合作直招到公司做.NET开发,现如今在某三线城市做后端技术经理,7年开发经验(5年.Net,2年.NE ...
- 浅谈Linux环境下Socket选项的设置
0.前言 TCP/IP协议栈是Linux内核的重要组成部分和网络编程的基石,虽然Linux和BSD有很大的联系,但是对于某些Socket选项和内核操作仍然存在差异,因此文中适用场景均为CentOS环境 ...
- elasticsearch使用BulkProcessor批量入库数据
在解决es入库问题上,之前使用过rest方式,经过一段时间的测试发现千万级别的数据会存在10至上百条数据的丢失问题, 在需要保证数据的准确性的场景下,rest方式并不能保证结果的准确性,因此采用了el ...
- TypedValue: 使用TypedValue将dip值转换成px值
之前自己一直手工编写函数来实现dip值到px值,今天无意中发现android本身就带有类似的函数来实现这种转换过程,就是 TypedValue.applyDimension public class ...
- Android通过ksoap2这个框架调用webservice大讲堂
昨天有人问我Android怎么连接mysql数据库,和对数据库的操作呀,我想把,给他说说json通信,可是他并不知道怎么弄,哎算了吧,直接叫他用ksoap吧,给他说了大半天,好多零碎的知识,看来还是有 ...
- vim支持golang函数调整
golang函数跳转需要借助godef实现 godef安装如下 go get -v github.com/rogpeppe/godef go install -v github.com/rogpepp ...
- SpringMVC:HandlerInterceptor log 日志
springMVC:HandlerInterceptor拦截器添加系统日志(权限校验)代码收藏 - LinkcOne - CSDN博客https://blog.csdn.net/qq_22815337 ...
- vim 显示行号 临时&永久
设置vim 永久显示行号 - electrocrazy的博客 - CSDN博客https://blog.csdn.net/electrocrazy/article/details/79035216 v ...