我不了解两个查询之间的区别,请参见图片。 注意最后的条件。 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为null或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
答案 0 :(得分:2)
NULL不是值NULL(根据WIKI - NULL):
空(或NULL)是结构化查询语言中使用的特殊标记 表示数据库中不存在数据值。
请勿将其与0值混淆。空值表示 缺乏价值-缺乏价值与价值不一样 零的答案与缺少答案的方法不同 作为“否”的答案。例如,请考虑以下问题: 亚当拥有书籍吗?”答案可能是“零”(我们知道他拥有 无)或“空”(我们不知道他拥有多少)。在数据库中 表中,报告此答案的列将开始时没有值 (由Null标记),并且不会使用“零”值进行更新 直到我们确定亚当没有书为止。
SQL null是状态,而不是值。这种用法与 大多数编程语言,其中引用的空值表示它 没有指向任何对象。
由于Null不是任何数据域的成员,因此不将其视为 “值”,而是表示缺少的标记(或占位符) 价值。因此,与Null的比较永远不会导致 是或否,但总是在第三个逻辑结果中, 未知。
也就是说:
1 = 0
为假,但1 = NULL
为未知1 != 0
为TRUE,但1 != NULL
也不为人 WHERE子句中的UNKNOWN
状态等效于FALSE。
这很直观-因为x为NULL(未知),所以我们不能说x = 1还是x!= 1为真-在两种情况下,比较结果都是未知的。
由于上述原因,SQL中有一些特殊的运算符可以检查列是否为空-x IS NULL
和x IS NOT NULL
。
您可以在以下简单演示中看到此行为:http://www.sqlfiddle.com/#!9/9f78b0/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
的值为UNKNOWN,相当于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) |
答案 1 :(得分:0)
在使用INT(11)时, free 列中的值可以在-2147483648和2147483647之间
free 列的默认值为 NULL (表示未知或未设置,不表示0或任何已知数字,注意:始终为NULL = NULL false ,因为NULL不等于NULL)
因此,当您使用free=0 or free is null
语句时,它表示free仅等于0或未设置free时(NULL),否则为 false
但是当您使用free!=1
时,如果free为0,-1,4145和...,则为 true 。
每个已知的数字,但1 AND NULL
PS:两者都可以是true,这取决于您要从查询中获得什么
如果free仅在free时为1,否则为0或NULL,则free=0 or free is null
是正确的语句。但是对于MySQL手册中的布尔值,您可以使用Bool和Boolean, tinyint的瞬间别名:
布尔型,布尔型:这些类型是TINYINT(1)的同义词。值 零被认为是错误的。非零值被认为是正确的。