mysql null值排序

本文介绍MySQL中处理NULL值排序的方法,包括使用isnull函数和特殊符号技巧,确保NULL值按需求排列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MySQL中order by 排序遇到NULL值的问题 MySQL数据库,在order by排序的时候,如果存在NULL值,那么NULL是最小的,ASC正序排序的话,NULL值是在最前面的。 如果我们想让NULL排在后面,让非NULL的行排在前面该怎么做呢?


MySQL数据库在设计的时候,如果字段允许NULL值,那么对该字段进行排序的时候需要注意那些值为NULL的行。


我们知道NULL的意思表示什么都不是,或者理解成“未知”也可以,它与任何值比较的结果都是false,


默认情况下,MySQL会认为NULL值比其他类型的数据小, 也就是说,在order by排序的时候,NULL是最小的,ASC正序排序的话,NULL值是在最前面的。 如果我们想让NULL排在后面,让非NULL的行排在前面该怎么做呢?


下面我们通过一个小例子,来说明这个情况。


首先,创建一个测试数据表 test_user,


mysql> create table test_user(-> id int unsigned not null auto_increment,-> username varchar(10) not null,-> age int,-> primary key (id))-> engine=myisam-> default charset=utf8-> ; Query OK, 0 rows affected (0.14 sec)


填充6条数据,其中3条设置了age值,另外3条age值为NULL


mysql> insert into test_user values(1,'hutuseng1',28),(2,'hutuseng2',30); Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0


mysql> insert into test_user(username) values('hutuseng3'),('hutuseng4'),('hutuseng5'); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0


mysql> insert into test_user values(6,'hutuseng6',23); Query OK, 1 row affected (0.00 sec)


mysql> select * from test_user; +----+-----------+------+ | id | username | age | +----+-----------+------+ | 1 | hutuseng1 | 28 | | 2 | hutuseng2 | 30 | | 3 | hutuseng3 | NULL | | 4 | hutuseng4 | NULL | | 5 | hutuseng5 | NULL | | 6 | hutuseng6 | 23 | +----+-----------+------+ 6 rows in set (0.00 sec)


我们按照age字段从小到大排序,我们看到NULL值是最小的,排在了最前面


mysql> select * from test_user order by age; +----+-----------+------+ | id | username | age | +----+-----------+------+ | 3 | hutuseng3 | NULL | | 4 | hutuseng4 | NULL | | 5 | hutuseng5 | NULL | | 6 | hutuseng6 | 23 | | 1 | hutuseng1 | 28 | | 2 | hutuseng2 | 30 | +----+-----------+------+ 6 rows in set (0.00 sec)


按照age字段从大到小排序,我们看到NULL值确实是最小的,排在了最后面


mysql> select * from test_user order by age desc; +----+-----------+------+ | id | username | age | +----+-----------+------+ | 2 | hutuseng2 | 30 | | 1 | hutuseng1 | 28 | | 6 | hutuseng6 | 23 | | 3 | hutuseng3 | NULL | | 4 | hutuseng4 | NULL | | 5 | hutuseng5 | NULL | +----+-----------+------+ 6 rows in set (0.00 sec)


这里有个需要注意的事项,就是NULL值本身是无法排序的,也就是说一个NULL是无法和另外一个NULL比较的。 你可能已经发现了,那三个NULL值的行,不管正序还是倒序,顺序都是一致的,当然也可能不一致。


那如果在对age进行正序排序的时候,我们希望NULL值的记录在最后面显示,那该如何做呢?


1、重新生成一列,比如agenull,利用is null操作符,把NULL值的行变成1,非NULL值的行变成0,先对该字段排序,再对age排序


mysql> select *,age is null as agenull from test_user order by agenull,age; +----+-----------+------+---------+ | id | username | age | agenull | +----+-----------+------+---------+ | 6 | hutuseng6 | 23 | 0 | | 1 | hutuseng1 | 28 | 0 | | 2 | hutuseng2 | 30 | 0 | | 3 | hutuseng3 | NULL | 1 | | 4 | hutuseng4 | NULL | 1 | | 5 | hutuseng5 | NULL | 1 | +----+-----------+------+---------+ 6 rows in set (0.01 sec)


2、直接利用isnull函数对age列求值,跟第一种方法的道理是一样的


mysql> select * from test_user order by isnull(age),age; +----+-----------+------+ | id | username | age | +----+-----------+------+ | 6 | hutuseng6 | 23 | | 1 | hutuseng1 | 28 | | 2 | hutuseng2 | 30 | | 3 | hutuseng3 | NULL | | 4 | hutuseng4 | NULL | | 5 | hutuseng5 | NULL | +----+-----------+------+ 6 rows in set (0.00 sec)


3、还可以利用MySQL中的一个小技巧,在字段前面加上一个负号,也就是减号,ASC改成DESC ,DESC改成ASC


mysql> select * from test_user order by -age desc; +----+-----------+------+ | id | username | age | +----+-----------+------+ | 6 | hutuseng6 | 23 | | 1 | hutuseng1 | 28 | | 2 | hutuseng2 | 30 | | 3 | hutuseng3 | NULL | | 4 | hutuseng4 | NULL | | 5 | hutuseng5 | NULL | +----+-----------+------+ 6 rows in set (0.00 sec)


所以,在设计数据库的时候,如果某个字段要进行排序的话,最好不要为NULL。




SELECT handle_person, create_date,handle_person IS NULL AS handlePersonNull FROM tb_event_collect WHERE 1 = 1 ORDER BY handlePersonNull DESC, create_date DESC 

MySQL 中,NULL 表示一个未知、确定或者可知的。它并等同于零(0)或空字符串(''),而是一种特殊的标记,用于表示数据的缺失或未定义状态。例如,在数据库表中,如果某一行的某个字段没有被赋,则该字段的通常会被设置为 NULL [^1]。 ### NULL 的含义 - **未知**:当数据尚未确定时,可以使用 NULL 表示该尚未被提供。 - **可知**:某些情况下,即使尝试获取数据,也可能因为某些限制或条件而无法获得具体的。 - **特殊含义**:对于某些特殊的数据类型,如 `TIMESTAMP` 和具有 `AUTO_INCREMENT` 属性的列,NULL 可能具有特殊的含义。例如,向 `TIMESTAMP` 列插入 NULL 时,系统会自动插入当前时间;向 `AUTO_INCREMENT` 列插入 NULL 时,系统会生成一个递增的整数 [^4]。 ### NULL 的使用方法 在使用 NULL 时,需要注意以下几点: 1. **判断 NULL **:由于 NULL 能直接使用普通的比较运算符(如 `=`、`!=`)进行判断,必须使用 `IS NULL` 或 `IS NOT NULL` 来判断一个字段是否为 NULL。此外,`<=>` 是一种安全等于运算符,可以用于比较两个是否相等,包括 NULL 的情况 。 2. **NULL 与运算**:任何包含 NULL 的表达式结果通常也会是 NULL。例如,`1 + NULL` 的结果是 NULL,`CONCAT('Invisible', NULL)` 的结果也是 NULL [^3]。 3. **统计行数**:在使用 `COUNT(column_name)` 函数时,它只会统计非 NULL 的行数。因此,如果需要统计所有行(包括 NULL ),应使用 `COUNT(*)` [^1]。 4. **索引与 NULL **:在某些类型的索引中,如空间索引,列必须为 NOT NULL。这意味着如果列允许 NULL ,则可能会影响索引的性能或有效性 [^1]。 5. **排序NULL **:在使用 `ORDER BY` 排序时,NULL 的处理方式取决于排序顺序。在升序排序中,NULL 会排在所有其他之前;而在降序排序(DESC)中,NULL 会排在所有其他之后 [^1]。 ### 示例代码 以下是一些常见的 SQL 查询示例,展示了如何处理 NULL : ```sql -- 查询某个字段为 NULL 的记录 SELECT * FROM table_name WHERE column_name IS NULL; -- 查询某个字段NULL 的记录 SELECT * FROM table_name WHERE column_name IS NOT NULL; -- 使用 COUNT(*) 统计所有行数 SELECT COUNT(*) FROM table_name; -- 使用 COUNT(column_name) 统计非 NULL 行数 SELECT COUNT(column_name) FROM table_name; -- 使用 COALESCE 函数将 NULL 替换为默认 SELECT COALESCE(column_name, 'default_value') FROM table_name; ``` ### 建议 - **避免使用 NULL **:在设计数据库时,尽量为字段设置合理的默认,而是使用 NULL 。这可以减少因 NULL 带来的复杂性和潜在问题 。 - **合理处理 NULL **:如果必须使用 NULL ,则应确保在查询和业务逻辑中正确处理这些,以避免出现意外结果 [^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值