MySQL必会——聚集函数与分组函数

前言

这一篇博客是SQL zoo网站第5章:SUM and COUNT的精选习题解析,主要涉及聚集函数和分组子句的使用。这一章比起之前的子查询来说相对比较简单。

聚集函数

有时候,我们并不需要将所有数据都查找出来,而是对这些数据进行汇总,MySQL中提供这类用途的函数,它们统称为聚集函数。这类函数能够完成诸如下面的功能:

  • 统计符合特定条件的数据项行数;
  • 计算表中数据项某一列数值的总和;
  • 寻找或者计算表中数据项的最大值、最小值或者平均值。

我们不需要将所有数据都查找出来,因为我们实际并不需要它们,查找出它们会造成时间和空间资源的浪费。取而代之,聚集函数能够汇总这些数据,根据需要选用指定的聚集函数就能返回需要的数据。

另外注意,聚集函数往往是输入多个值(一列多行),而输出只有单个值的函数

SUM()函数

SUM()函数用来返回指定列值的总和,括号内应填写列名作为输入参数。同时,SUM()函数也支持计算多列值之间的运算。同时SUM()函数会忽略列值为NULL的行。

题1.展示世界的总人口。

非常简单,直接对population列使用SUM()函数即可。

SELECT SUM(population)
FROM world;

去除重复

有时候我们的数据往往包含了大量的重复值,但我们只想让查询结果每种只显示一个就行了。MySQL提供DISTINCT参数给我们实现去重的功能。DISTINCT参数添加在需要去重的列名前即可生效。DISTINCT无法单独使用,其后必须指定列名

题2.列出所有的洲份, 每個只有一次。

也很简单,直接在continent列前添加上DISTINCT即可。

SELECT DISTINCT continent
FROM world;

count()函数

COUNT()函数用于对数据进行计数,返回表中指定条件或者全部的行数目。其中括号内可以填写*表示对表中所有行进行计数不管列中是否为空值(NULL)都会计算。而如果括号内填写具体的列名作为参数时,表示只针对指定列同时有值的行进行计数,而空值行将不算在内

题4.有多少個國家具有至少百萬(1000000)的面積。

经典的条件筛选查询,然后加上COUNT()函数就完事了。

SELECT COUNT(name)
FROM world
WHERE area >= 1000000;

分组查询GROUP BY子句

分组主要是为了解决需要对数据按照某一列值进行归类划分的问题。GROUP BY跟上指定列名就可以在查询时将数据按照列名的不同值进行合并归类,而且往往使用分组查询的场景是会搭配聚集函数进行统计的。

使用形式如下所示:

SELECT column_name, function(column_name)
FROM table_name
WHERE condition
GROUP BY column_name;

虽然GROUP BY非常强大,但是使用这个子句时有一些注意事项:

  • GROUP BY子句中的每个列都必须是可以被检索的列名或者是与列名相关的有效表达式,但不能是聚集函数,也不能对这些列名或者表达式取别名
  • 除聚集函数外,SELECT语句中存在的所有列名都必须出现在GROUP BY子句中。这一条规定似乎在SQL99标准中不再要求,但是想想看,没有被你分组的列显示也是残缺的局部值,并没有什么意义。
  • 如果分组列中存在NULL值,无论多少行都会被归为相同的一组
  • GROUP BY子句必须出现在WHERE子句之后,ORDER BY子句之前

题7.對於每一個洲份,顯示洲份和至少有1000萬人(10,000,000)口國家的數目。

刚开始接触可能觉得无从下手,实际上,如果需求描述中出现“每”这样的字眼时,往往就说明需要使用GROUP BY子句来对这个列进行分组了。所以这里很明显需要使用到GROUP BY continent。

SELECT continent, COUNT(name)
FROM world
WHERE population >= 10000000
GROUP BY(continent);

过滤分组

我们的需求进一步提高了,现在不仅要对数据分组,而且我们还只要分组数据中的一部分,也就是说,我们希望在分组数据中进一步筛选过滤。之前有学过筛选数据使用WHERE子句,不过很可惜WHERE并不能胜任这项工作,因为WHERE只能对表中所有行进行过滤,对于WHERE来说并没有分组的概念

为了能够满足我们的这种需求,MySQL提供了另外一个子句可供使用,那就是HAVING子句。HAVING子句在用法上与WHERE没有什么区别,只是它必须要伴随着GROUP BY子句才能使用,表示过滤分组。使用形式如下:

SELECT column_name, function(column_name)
FROM table_name
WHERE condition1
GROUP BY column_name
HAVING condition2;

题8.列出有至少100百萬(1億)(100,000,000)人口的洲份。

这里要求是列出洲份,实际上就是隐式地要求对数据按洲份进行分组,同时还要求计算各个州的总人口,并从中筛选出大于1亿人口的分组。这就是典型的使用GROUP BY和HAVING子句的范例。

SELECT continent
FROM world
GROUP BY continent
HAVING SUM(population)>= 100000000;

然后我记得当时我没用HAVING,用了一种特别蠢的方法:

SELECT continent 
FROM(SELECT continent,SUM(population) AS pop 
     FROM world a 
     GROUP BY continent) a 
WHERE pop>=100000000;

总结

本篇博客主要介绍聚集函数和分组子句的使用,结合一些在线习题进行举例说明,希望能够帮助到初学者理解。

你可能感兴趣的:(数据库,数据库,sql,mysql)