NOT NULL列用IS NULL也能查到数据?

导读

datetime列设置了NOT NULL约束,但查询条件IS NULL却能返回结果,奇怪吗?

测试表DDL

CREATE TABLE `t1` (
  `id` int(11) DEFAULT NULL,
  `dt` datetime NOT NULL DEFAULT '0000-00-00 00:00:00'
) ENGINE=InnoDB;

插入测试数据:

yejr@imysql.com> insert into t1(id) select 1;  --- 不指定dt列的值
yejr@imysql.com> insert into t1 select 2, now();  --- 指定dt列的值为now()
yejr@imysql.com> insert into t1(id) select 3;  --- 不指定dt列的值

查询数据:

yejr@imysql.com> select * from t1 where dt is null;
+------+---------------------+
| id   | dt                  |
+------+---------------------+
|    1 | 0000-00-00 00:00:00 |
|    3 | 0000-00-00 00:00:00 |
+------+---------------------+
2 rows in set (0.00 sec)

有没有觉得很奇怪,为什么查到了2条 dt 列值为 '0000-00-00 00:00:00' 的记录?

先查看执行计划:

yejr@imysql.com> desc select * from t1 where dt is null\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t2
   partitions: NULL
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 5
     filtered: 20.00
        Extra: Using where
1 row in set, 1 warning (0.00 sec)

yejr@imysql.com> show warnings\G
*************************** 1. row ***************************
  Level: Note
   Code: 1003
Message: /* select#1 */ select `yejr`.`t1`.`id` AS `id`,`yejr`.`t2`.`dt` AS `dt` from `yejr`.`t1` where (`yejr`.`t1`.`dt` = '0000-00-00 00:00:00')

发现 IS NULL 条件被转换了,所以才能查到结果,这是为什么呢? 我尝试了调整SQL_MODE,发现并没什么卵用,最后还是在官方文档找到了答案:

For DATE and DATETIME columns that are declared as NOT NULL, you can find the special date '0000-00-00' by using a statement like this: SELECT * FROM tbl_name WHERE date_column IS NULL This is needed to get some ODBC applications to work because ODBC does not support a '0000-00-00' date value. See Obtaining Auto-Increment Values, and the description for the FLAG_AUTO_IS_NULL option at Connector/ODBC Connection Parameters.

文档出自:12.3.2 Comparison Functions and Operators, https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html

啊,对了,MySQL版本是 5.7.21。

最后的结论告诉我们,遇到问题时,查询官档是有多么重要

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏小灰灰

mysql之索引的工作机制

当db的量达到一定数量级之后,每次进行全表扫描效率就会很低,因此一个常见的方案是建立一些必要的索引作为优化手段,那么问题就来了:

4429
来自专栏Java Web

模仿天猫实战【SSM版】——项目起步

3424
来自专栏黑泽君的专栏

day05_MySQL学习笔记_02

    注:每个表中至少要有一个主键。 主键用于唯一地标识表中的每一条记录,可以定义一列或多列为主键。 

902
来自专栏Albert陈凯

理解SQL原理SQL调优你必须知道的10条铁律

原文地址: http://www.nowamagic.net/librarys/veda/detail/1502 我们做软件开发的,大部分人都离不开跟数据库打...

3745
来自专栏IT技术精选文摘

MySQL的索引是什么?怎么优化?

1014
来自专栏Java后端生活

MySQL(八)DQL之连接查询

1718
来自专栏james大数据架构

你真的会玩SQL吗?简单的数据修改

你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接、外连接 你真的会玩SQL吗?三范式、数据完整性 你真...

2007
来自专栏chenssy

MySQL的索引是什么?怎么优化?

索引类似大学图书馆建书目索引,可以提高数据检索的效率,降低数据库的IO成本。MySQL在300万条记录左右性能开始逐渐下降,虽然官方文档说500~800w记录,...

963
来自专栏程序员宝库

Mysql - JOIN 详解

一个完整的SQL语句中会被拆分成多个子句,子句的执行过程中会产生虚拟表(vt),但是结果只返回最后一张虚拟表。从这个思路出发,我们试着理解一下JOIN查询的执行...

2983
来自专栏battcn

MySQL - WHERE优化篇

在做JAVA开发中,通过指令重拍会对代码做一定程度的优化,在数据库中 MYSQL优化器也做了一系列相关优化工作,下面要介绍的就是数据库做的内置优化

1122

扫码关注云+社区

领取腾讯云代金券