mysql中case when null then 的问题?难!

MySQL里的IFNULL函数,其实跟NVL挺像的,但又不完全一样。
今天就来好好聊聊这个IFNULL函数,希望能让你更清楚地了解它是怎么工作的。

IFNULL(expr1 , expr2 )这个函数,说白了就是:如果你给的第一个参数expr1 不是NULL,那它就直接返回expr1 ;如果expr1 是NULL,那它就返回你给的第二参数expr2 这个函数返回的值,到底是数字还是字符串,得看它在什么环境下使用。

举个例子,比如你想查一个字段,如果这个字段是空的,就显示0,你可以这样写:SELECT IFNULL(1 , 0); 结果就是1 ,因为第一个参数不是NULL。
再比如,SELECT IFNULL(0, 1 0); 结果就是0,第一个参数是0,不是NULL,所以返回第一个参数。
还有,像这种SELECT IFNULL(1 /0, 1 0);,虽然1 /0会出错,但它还是会返回1 0,因为出错的部分被IFNULL给处理了。
最后一个SELECT IFNULL(1 /0, 'yes');,结果就是'yes',道理跟上面一样。

跟IFNULL类似的还有一个IF函数,IF(expr1 , expr2 , expr3 )。
这个函数的意思是:如果expr1 是真(也就是不等于0且不是NULL),那就返回expr2 ;如果expr1 是假,那就返回expr3 这个函数返回的值,也是看它在什么环境下使用。

比如SELECT IF(1 >2 , 2 , 3 );,结果就是3 ,因为第一个条件是假。
SELECT IF(1 <2>再比如SELECT IF(strcmp('test', 'test1 '), 'yes', 'no');,结果就是'no',因为字符串比较的结果是假。

需要注意的是,IF函数里的expr1 会当作整数来计算。
所以如果你要测试的是浮点数或字符串,最好先用比较操作符来比较。

举个例子,SELECT IF(0.1 , 1 , 0);,结果就是0,因为0.1 被转换成整数0,所以条件变成了IF(0)。
这可能不是你想要的结果。
而SELECT IF(0.1 0, 1 , 0);,结果就是1 ,因为它比较的是浮点数0.1 是否不等于0,这符合条件,所以返回1
最后是CASE语句,它有两种写法。
第一种是CASE value WHEN [compare-value] THEN result [WHEN [compare-value] THEN result...] [ELSE result] END;这种是按照value等于哪个compare-value来返回对应的result。
如果没有匹配的compare-value,如果有ELSE部分,就返回ELSE后面的result;如果没有ELSE部分,就返回NULL。

第二种是CASE WHEN [condition] THEN result [WHEN [condition] THEN result...] [ELSE result] END;这种是按照哪个condition为真来返回对应的result。
如果没有匹配的condition,如果有ELSE部分,就返回ELSE后面的result;如果没有ELSE部分,就返回NULL。

举个例子,SELECT CASE 1 WHEN 1 THEN 'one' WHEN 2 THEN 'two' ELSE 'more' END; 结果就是'one',因为1 等于第一个compare-value。
SELECT CASE WHEN 1 >0 THEN 'true' ELSE 'false' END; 结果是'true',因为第一个condition为真。
SELECT CASE BINARY 'B' WHEN 'a' THEN 1 WHEN 'b' THEN 2 END; 结果是NULL,因为没有匹配的condition。

MySQL索引失效的场景

MySQL索引有时候也挺让人头疼的,明明加了索引,查询速度却变慢了,这通常是因为索引失效了。
咱们来聊聊索引失效的几种常见情况:
首先,联合索引不满足最左匹配原则是个常见的问题。
比如说你有个联合索引(sn, name, age),查询的时候必须从最左边的字段sn开始匹配,像sn单独查询、或者sn和name组合查询、或者三个字段一起查,这样索引就能好好工作。
但如果你只查name、或者name和age组合、或者只查age,那索引就白加了,因为顺序不对。

其次,用LIKE做模糊查询的时候,通配符%要是放在最前面,索引也帮不上忙。
比如LIKE '%张三'就找不到索引的影子,而LIKE '张三%'则能让索引派上用场。

再比如,查询条件中对索引列做了运算,索引也失效了。
比如age+1 =1 8 这样的条件,索引就无能为力了。

还有,如果在查询条件中对索引列用了函数,比如IFNULL(address,'未知')='高老庄',索引同样会失效。

此外,索引列和查询条件中的数据类型不一致,需要进行类型转换的时候,索引也会失效。
比如address是字符串类型,但查询条件却是address=1 2 3 (1 2 3 是整数),这样MySQL就不得不进行类型转换,索引也就没法用了。

最后,使用isnotnull对索引列进行筛选时,索引可能会失效,这跟MySQL的版本和优化器有关。
相比之下,使用isnull通常能正常触发索引。

为了避免索引失效,咱们在设计索引和使用查询的时候,要注意几点:联合索引要按顺序匹配,LIKE查询时通配符%别放最前面,查询条件里别对索引列进行运算或用函数,确保数据类型一致,注意isnotnull可能对索引的影响。
只要把这些地方注意到了,索引就能发挥大作用,查询速度自然也会快起来。