MySQL 中 count() 过滤的"异常"行为 及 “字段”即“变量”
关于 MySQL count() 过滤的异常行为的问题:
select count(null) from t1; #返回0,这符合预期, 因为 count 传入的值不能为 null 。
select count(x<200) from t1; #返回总行数,无法过滤行。
select count(x<200 or null) from t1; #可以统计出 x 小于200的行的数量。
select count(x<200 and null) from t1; #返回127399,不知道这个值是怎么得出来的。
表为innodb, 共计130000条记录
-----------------------------------------------
据本人的试验和总结,对以上问题得出以下结论:
一、 根据 MySQL 中 关系运算符 的运算结果是 0 或 1 ,以及 MySQL 中 逻辑运算符 的运算结果。本人认为:MySQL 中 0 为 假 、非0 为 真 。
二、根据测试 本人认为 MySQL 中的 逻辑运算符 也具有 短路特性 。
三、根据 MySQL 官方文档 可知,其实 count 函数 的作用是:
count(表达式)
返回 该表达式 结果非NULL 的行数。
事实上,当 count 函数 的参数为 NULL 时不会进行计算,只要参数 非NULL 都会进行计算(当参数为 0 时也会进行计算)。
例如,假设有某表 tb :
select count(null) from tb; #不会把任何一行计算在内。
select count(*) from tb; #把每一行都计算在内。
select count(0) from tb; #把每一行都计算在内。
select count(1) from tb; #把每一行都计算在内。
select count(2) from tb; #把每一行都计算在内。
假设 n 是 tb 表 中的一个字段。在某行记录中 n 字段的值为 100 :
select count(n < 50) from tb;
#不会跳过该行(把该行计算在内)。因为在该行中 n 的值为 100, n < 50 的运算结果为 0 。
select count(n < 50 or null) from tb;
#跳过该行(不会进行计算),n < 50 的运算结果为 0 ,但因为 or 的 短路特性 所以表达式的结果为 NULL 。
-----------------------------------------------
☆ “字段” 即 “变量” :
在 MySQL 中,如果函数被调用时,其参数中出现了某个字段名(列名),那么函数就会取每一行记录中对应字段(列)的值 代入参数中进行处理。
这里 字段名(列名)就像是 变量名 ,每行记录中 该字段(列)的值 就像是 变量的值 。
where、having子句 及 select 等语句也同上。例如:
select 列1,列2,列1 - 列2 from 表名 where (列1 - 列2) > 200;
所以我们应该把 字段名 视为 变量名,字段 视为 变量。