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;
 
    所以我们应该把 字段名 视为 变量名,字段 视为 变量。

 

posted @ 2017-11-10 20:38  Uncle_Jay  阅读(1236)  评论(0编辑  收藏  举报