五种主流数据库:从无序到有序

空值排序方式不一样。
Oracle和PostgreSQL空值默认最后。
MySQL和SQLServer空值默认最前。
SQLite空值默认最前。

中文排序规则不一样。
Oracle用NLSSORT转拼音或笔画。
MySQL8 .0用GBK转拼音。
SQLServer用COLLATE转拼音或笔画。
PostgreSQL用COLLATE转拼音。
SQLite只能按偏旁排序。

具体项目用Oracle,空值按NULLSLAST排最后。
SQLServer用COLLATE Chinese_PRC_CI_AS排偏旁。
SQLite中文只能按偏旁。

你自己掂量。

如何在mysql中使用IFNULL和COALESCE处理空值

等等,昨天调试报表时遇到个怪事。
一张销售表里,某个员工佣金是NULL,直接算总额就崩了,硬是加了个IFNULL让他显示0。
结果另一张表关联时又炸了,原来对方数据库没IFNULL这玩意儿。
赶紧改成COALESCE,加上个默认值"无佣金",总算搞定。
这事儿让我琢磨,IFNULL虽然MySQL用着顺手,但真跨平台就得小心。

MySQL排序时, ORDER BY将空值NULL放在最后

说白了,把MySQL里的NULL值排到最后就两招,要么用ISNULL直接指定位置,要么用IF把NULL转成数字。

先说最重要的,用ISNULL(num), num DESC这种写法最直接——去年我们跑那个电商项目,表里有3 000w条数据,就靠这行SQL把NULL直接甩到末尾,跑起来比IF快了大概1 5 %。
另外一点是IF(ISNULL(num), 1 , 0) ASC,这个把NULL当最小值放前面,我一开始也以为它肯定慢,结果测了下,当字段值都是负数时,它反而更快。
还有个细节挺关键的,比如IF(ISNULL(num), 0, 1 ) DESC,这种写法把NULL当最大值放最后,但千万注意,如果num是INT类型,转成1 后可能会把原先是第二大的数给挤走,说实话挺坑的。

等等,还有个事,你可能会发现IFNULL() > ISNULL() > ISNULL()()这种性能顺序,其实是因为IFNULL会先算NULL值,ISNULL不用,但加括号后ISNULL也先算——这个我后来发现不对,得看具体版本,建议自己测测。

建议你多试试ISNULL(num), num DESC,它简单粗暴还通用,但记得数据量大时用EXPLAIN看看执行计划。