mysql Having字句

张锋 4年前 访问:872 评论:0 关注:0

查询不包含NULL的集合

COUNT函数的使用方法有COUNT(*)和COUNT(列名)两种,
它们的区别有两个:第一个是性能上的区别;第二个是COUNT(*)可以用于NULL,
而COUNT(列名)与其他聚合函数一样,要先排除掉NULL的行再进行统计。
第二个区别也可以这么理解:COUNT(*)查询的是所有行的数目,而COUNT(列名)查询的则不一定是。对一张全是NULL的表NullTbl执行SELECT子句就能清楚地知道两者的区别了。

在对包含null的列使用时,count(*)和count(列名)查询的结果是不一样的。

SELECT COUNT(*),COUNT(col) FROM A;

这里有一张存储了学生提交报告的日期的表Students,

学生提交报告后,“提交日期”列会被写入日期,而提交之前是NULL。现在我们需要从这张表里找出哪些学院的学生全部都提交了报告(即理学院、经济学院)。如果只是用WHEREsbmt_date IS NOT NULL这样的条件查询,文学院也会被包含进来,结果就不正确了(因为文学院学号为102的学生还没有提交)。正确的做法是,以“学院”为GROUP BY的列生成下面这样的子集。

所有学生都提交了报告的学院有哪些

这样生成的4个子集里,想要的是S1和S4。那么,这2个子集具备而其他子集不具备的特征是什么呢?答案是“COUNT(*)和COUNT(sbmt_date)结果一致”。这是因为S2和S3这2个子集里存在NULL。因此,答案应该是下面这样。

SELECT dpt FROM Students GROUP BY dpt HAVING COUNT(*) = COUNT(sbmt_date);

使用CASE表达式也可以实现同样的功能,而且更加通用。

SELECT dpt FROM Students GROUP BY dpt HAVING COUNT(*) = SUM(CASE WHEN sbmt_date IS NOT NULL THEN 1 ELSE 0 END);

可以看到,使用CASE表达式时,将“提交日期”不是NULL的行标记为1,将“提交日期”为NULL的行标记为0。在这里,CASE表达式的作用相当于进行判断的函数,用来判断各个元素(=行)是否属于满足了某种条件的集合。这样的函数我们称为特征函数(characteristic function),或者从定义了集合的角度来将它称为定义函数。

1.表不是文件,记录也没有顺序,所以SQL不进行排序。

2.SQL不是面向过程语言,没有循环、条件分支、赋值操作。

3.SQL通过不断生成子集来求得目标集合。SQL不像面向过程语言那样通过画流程图来思考问题,而是通过画集合的关系图来思考。

4.GROUP BY子句可以用来生成子集。

5.WHERE子句用来调查集合元素的性质,而HAVING子句用来调查集合本身的性质。

评论

还没有人评论 ~

❤❤❤❤❤❤
心情
此图名叫《暗淡蓝点》
1990年2月14日,由旅行者1号拍摄,
蓝色的点就是地球
或许你看不清,因为地球在宇宙中太小了。