如果列中有空值,则查询条件

xpszyzbs  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(342)

我不明白这两个查询之间的区别,请看图片。注意最后一个条件。mysql版本是5.7有什么神奇之处?

select distinct(pc) as aggregate 
from `installers` 
where 
    `success` =1 
    and 
    date(created_at) >= '2018-08-15' 
    and 
    date(created_at) <= '2018-08-21' 
    and 
    (free=0 or free is null)

(free为空或free=0)

select distinct(pc) as aggregate 
from `installers` 
where 
    `success` =1 
    and 
    date(created_at) >= '2018-08-15' 
    and 
    date(created_at) <= '2018-08-21' 
    and 
    free!=1

免费=1

表结构

CREATE TABLE `installers` (
    `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
    `driver_id` BIGINT(20) UNSIGNED NOT NULL,
    `created_at` TIMESTAMP NULL DEFAULT NULL,
    `updated_at` TIMESTAMP NULL DEFAULT NULL,
    `success` TINYINT(4) NULL DEFAULT NULL,
    `version` BIGINT(20) UNSIGNED NULL DEFAULT NULL,
    `pc` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_unicode_ci',
    `status` VARCHAR(180) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
    `error` VARCHAR(180) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
    `free` INT(11) NULL DEFAULT NULL,
    `time` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
    PRIMARY KEY (`id`),
    INDEX `installers_created_at_index` (`created_at`),
    INDEX `installers_updated_at_index` (`updated_at`),
    INDEX `installers_driver_id_foreign` (`driver_id`),
    INDEX `installers_success_index` (`success`),
    INDEX `installers_version_index` (`version`),
    INDEX `installers_pc_index` (`pc`(191)),
    INDEX `installers_status_index` (`status`),
    INDEX `installers_error_index` (`error`),
    INDEX `installers_free_index` (`free`),
    INDEX `installers_time_index` (`time`),
    CONSTRAINT `installers_driver_id_foreign` FOREIGN KEY (`driver_id`) REFERENCES `drivers` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
)
COLLATE='utf8mb4_unicode_ci'
ENGINE=InnoDB
AUTO_INCREMENT=4709971
;

“free”的不同值为null,0,1

cngwdvgl

cngwdvgl1#

null不是值,null(根据wiki-null):
null(或null)是结构化查询语言中使用的一个特殊标记,用于指示数据库中不存在数据值。
这不应与值0混淆。空值表示缺少值-缺少值与值为零不是一回事,正如缺少答案与回答“否”不是一回事一样。例如,考虑“亚当拥有多少本书?”这个问题,答案可能是“零”(我们知道他一本也没有)或“零”(我们不知道他拥有多少)。在数据库表中,报告此答案的列将以no值(用null标记)开始,并且在我们确定adam没有书籍之前,它不会用值“零”进行更新。
sql null是一个状态,而不是一个值。这种用法与大多数编程语言完全不同,在大多数编程语言中,引用的空值意味着它不指向任何对象。
由于null不是任何数据域的成员,因此它不被视为“值”,而是表示没有值的标记(或占位符)。正因为如此,与null的比较永远不会得到true或false,但总是得到第三个逻辑结果unknown。
即: 1 = 0 是假的,但是 1 = NULL 是未知的 1 != 0 是真的但是 1 != NULL 也不得而知
这个 UNKNOWN where子句中的状态等同于false。
这是直观的-因为x是空的(未知),所以我们不能说x=1还是x!=1是正确的-在这两种情况下,比较结果都是未知的。
由于上述原因,sql中有一些特殊的操作符来检查列是否为null- x IS NULL 以及 x IS NOT NULL .
您可以在这个简单的演示中看到这种行为:http://www.sqlfiddle.com/#!9/9楼78b0/5

SELECT * FROM t;
| id |      x |
|----|--------|
|  1 |      1 |
|  2 |      0 |
|  3 | (null) |
SELECT * FROM t WHERE x =1;
| id | x |
|----|---|
|  1 | 1 |
SELECT * FROM t WHERE x != 1;
| id | x |
|----|---|
|  2 | 0 |

请注意,上面的查询只返回了 x = 2 但是跳过了记录 x = NULL 因为比较 x != NULL 计算为未知,相当于false。

SELECT * FROM t WHERE x IS NULL;

| id |      x |
|----|--------|
|  3 | (null) |
SELECT * FROM t WHERE x IS NOT NULL;
| id | x |
|----|---|
|  1 | 1 |
|  2 | 0 |
SELECT * FROM t WHERE x = 1 OR x IS NULL;
| id |      x |
|----|--------|
|  1 |      1 |
|  3 | (null) |
SELECT * FROM t WHERE x != 1 OR x IS NULL;
| id |      x |
|----|--------|
|  2 |      0 |
|  3 | (null) |
h7appiyu

h7appiyu2#

当您使用int(11)时,free列中的值可以在-2147483648和2147483647之间
自由列的默认值为null(表示未知或未设置,不表示0或任何已知数字,注意:null=null总是false,因为null不等于null)
所以当你使用 free=0 or free is null 语句,表示free仅等于0或free未设置(null),否则为false
但是当你使用 free!=1 当自由是0,-14145和。。。除了1和空以外的所有已知数字
ps:这两个都可以是真的,这取决于你想从你的查询中得到什么如果free只有在free时是1,否则是0或null,那么 free=0 or free is null 是正确的语句,但对于布尔值,根据mysql手册,您可以使用bool和boolean,它们目前是tinyint的别名:
bool,boolean:这些类型是tinyint(1)的同义词。零值被认为是错误的。非零值被认为是真的。

相关问题