先创建一张表用于演示:
CREATE TABLE `test1` (
`id` INT ( 11 ) NOT NULL,
`name` VARCHAR(255) not null,
`classid` VARCHAR(255),
`age` VARCHAR(255),
PRIMARY KEY ( `id` )) ENGINE = INNODB DEFAULT CHARSET utf8;
INSERT INTO test1 VALUES(1,'james','one',12);
INSERT INTO test1 VALUES(2,'zhangsan','one',NULL);
INSERT INTO test1 VALUES(3,'lisi','one',25);
INSERT INTO test1 VALUES(4,'wangwu','one','');
INSERT INTO test1 VALUES(5,'shanji','one',67);
INSERT INTO test1 VALUES(6,'james','',22);
INSERT INTO test1 VALUES(7,'james',NULL,23);
INSERT INTO test1 VALUES(8,'wangwu','two',36);
INSERT INTO test1 VALUES(9,'wangwu','two',24);
INSERT INTO test1 VALUES(10,'zhangsan','two',NULL);
INSERT INTO test1 VALUES(11,'zhangsan','two',9);
INSERT INTO test1 VALUES(12,'zhaoliu','two',12);
1、空的表达方式有两种,第一种是NULL,第二种是’ ‘。
判定方法:判断NULL 用IS NULL 或者 IS NOT NULL,判断空字符用 =’'或者<>/!= ’ ’ 来进行处理。
如果NULL不被当作空字符处理,应该返回的id是1、2、3、5、6、7、8、9、10、11、12。
注意:MySQL可以在含有NULL的列上使用索引。
1、max、min、avg和sum函数对null值采取的处理方式是:直接忽略。
2、count处理null值的处理方式需要分两种情况:
(1)count(*):返回的是所有记录的总和,含有null值的记录不会被忽略,也会被计算在内。
(2)count(字段名):如果这个列名中含有一个值为null,则该条记录会被忽略,此时的返回值为count(*)-1。
3、直接对表的age列的数值求和,此处我是忽略了NULL和空字符,和上面函数的结果是一样的,所以在使用sum()函数的时候是直接过滤掉了NULL和空字符。
4、直接对表的age列的数值求均值,数值和是230,12条记录,两条NULL,一条空字符。如果NULL和空字符都忽略的话结果为avg_9_age,但是函数的结果是23。证明空字符没有被忽略参与了计算!
5、如果对字段进行统计记录数的话,是忽略NULL但是不忽略空字符的。如果参数使用 * 的话是NULL和空字符都计算的。
6、因为创建表格的时候为了在age列加上空字符(int类型约束的时候加不上。。。),age字段类型是varchar的,但是在使用max()函数的时候出了问题!肉眼可见age字段最大的是67,但是返回的是9!所以尝试对字段的数据类型做了转换,结果正确。。
-- (1)使用CONVERT()函数对age字段做类型转化
SELECT
MAX( tt.float_num_age )
FROM
( SELECT CONVERT ( t.age, DECIMAL ( 10, 2 )) AS float_num_age FROM test1 AS t WHERE t.age != '' ) AS tt;
-- 结果:67.00
-- --------------------------------------------------------------------------------------------------------------
-- (2)使用CAST()函数对age字段做类型转化
SELECT
MAX( tt.float_num_age )
FROM
( SELECT CAST(t.age AS DECIMAL ( 10, 2 )) AS float_num_age FROM test1 AS t WHERE t.age != '' ) AS tt;
-- 结果:67.00
-- 对比:不去掉空值,可见NULL和空字符(convert和cast函数会转为0.00)对数据转换过程和使用max函数无影响。
SELECT
MAX( tt.float_num_age )
FROM
( SELECT CAST(t.age AS DECIMAL ( 10, 2 )) AS float_num_age FROM test1 AS t ) AS tt;
-- 结果:67.00
-- --------------------------------------------------------------------------------------------------------------
-- (3)使用CAST()函数对age字段做类型转化,转为int类型报错,貌似不能转为int
SELECT
MAX( tt.float_num_age )
FROM
( SELECT CONVERT ( t.age, INT) AS float_num_age FROM test1 AS t WHERE t.age != '' ) AS tt;
7、直接对age列使用min函数则会返回空字符,如果在对age做了数据类型转换后会返回0.00,因为convert和cast函数都会把空字符转换为0.00。
SELECT MIN(age) FROM test1;
-- ---------------------------------------------------------------------------------------
SELECT
MIN( t.float_num_age )
FROM
( SELECT CONVERT ( age, DECIMAL ( 10, 2 )) AS float_num_age FROM test1 ) AS t;
-- ---------------------------------------------------------------------------------------
SELECT id,CONVERT ( age, DECIMAL ( 10, 2 )) AS float_num_age FROM test1;
-- ---------------------------------------------------------------------------------------
SELECT id,cast( age AS DECIMAL ( 10, 2 )) AS float_num_age FROM test1;
1、空字符和NULL会被分组!
2、使用max或者min函数的时候如果字段数据类型是varchar,即使分组后也还是有影响的(好像废话。。。)