统计与聚合

统计查询

以下是 SQL 中最常用的函数的列表。它们的工作方式类似于 COUNT,但是对数据执行不同的计算。

FUNCTION DESCRIPTION
MAX returns the largest (maximum) number in a sets
MIN described
COUNT returns a count of the # of values in a set
COUNT DISTINCT returns a count of the # of unique (distinct) values in a set
EVERY returns true if all data inside is true (same as bool_and)
AVG returns the average (mean) of the set of numbers
SUM returns the sum of all the values in the set

以下示例使用 MIN,MAX 和 AVG 函数给出了 tracks 的范围和平均价格。

SELECT MAX(unit_price), MIN(unit_price), AVG(unit_price) FROM tracks;
MAX MIN AVG
1.99 0.99 1.0508050242649158

COUNT

原始数据的获取很不错,但是现在我们将开始实际进行一些汇总和转换! 我们将要学习的第一个也是最常用的聚合函数是 COUNT。COUNT 函数接受您提供的所有内容,并返回计数。

以下 SQL 将计算数据库中有多少相册。换句话说,我们将查询 ablums 表中的行数计数。在自己周围玩耍,查找艺术家和曲目表中的曲目。

SELECT COUNT(*) FROM albums;

不要使用 count(列名)或 count(常量)来替代 count(),count()是 SQL92 定义的标准统计行数的语法,跟数据库无关,跟 NULL 和非 NULL 无关。count(*) 会统计值为 NULL 的行,而 count(列名)不会统计此列为 NULL 值的行。

count(distinct col) 计算该列除 NULL 之外的不重复行数,注意 count(distinct col1, col2) 如果其中一列全为 NULL,那么即使另一列有不同的值,也返回为 0。

指定列

当 COUNT 遍历数据结果时,如果数据不为 NULL(SQL 术语中的 NULL 表示为空),则仅增加计数。进行 COUNT(*) 总是会返回表中存在的行数的全部计数,因为 splat(*)代表每一列,而且行中的所有列都不可能为 NULL。但是,如果您指定特定的列,则将返回该列不为 NULL 的行数的 COUNT。因此,对 composer 列进行计数:

SELECT COUNT(composer) FROM tracks;

COUNT DISTINCT

带有 count 函数的常用子句是 DISTINCT。DISTINCT 子句将计数更改为仅计算数据中唯一值的数量。在上方,我们获取了列出作曲家的曲目数量。如果我们实际上想查看曲目表中有多少个独特的作曲家,则可以将 COUNT 与 DISTINCT 子句一起使用,如下所示:

SELECT COUNT(DISTINCT composer) FROM tracks;

Aliases

这里有个简单的提示:请注意,上述数据集上的列标题并不清楚。SQL 可以很好地为您要获取的内容找到名称,但是通常,尤其是当我们开始创建更复杂的函数时,您将需要使用自己的别名作为数据。您可以在选择后使用 AS 关键字来执行此操作:

SELECT COUNT(*) AS "# of Tracks", COUNT(composer) AS "Non-Empty Composers", COUNT(*) - COUNT(composer) AS "Empty/Null Composers" FROM tracks;

GROUP BY

到目前为止,我们的汇总功能已遍及所有数据,但将汇总分为几组通常很有用。举例来说,我们不想获取所有曲目的计数,而是希望每种流派有多少曲目。这样做的一种方法是为每种类型编写一个单独的查询,如下所示:

SELECT COUNT(*) FROM tracks WHERE genre_id = 1;
SELECT COUNT(*) FROM tracks WHERE genre_id = 2;
SELECT COUNT(*) FROM tracks WHERE genre_id = 3;
.
.
.
SELECT COUNT(*) FROM tracks WHERE genre_id = n;

但是我们必须知道所有 genre_id 都是什么,并使用其他工具将所有结果重新组合在一起。幸运的是,我们有 GROUP BY 子句,这使它变得更加简单。GROUP BY 子句告诉数据库如何对结果集进行分组,因此我们可以更简单地将上面的查询编写为:

SELECT genre_id, COUNT(*) FROM tracks GROUP BY genre_id;

在此按计数对查询结果进行排序很有用,这样我们就可以查看哪些作曲家产生的曲目数量最多(至少在我们的数据库中)。

SELECT composer, COUNT(*) as "count" FROM tracks GROUP BY composer ORDER BY "count" DESC;

Multiple GROUP BYs

您可以按多个对象进行分组,并且仅在第一组内部创建第二组。尝试运行以下示例,该示例首先按流派然后按作曲家分组。

SELECT genre_id, media_type_id, COUNT(*) FROM tracks GROUP BY genre_id, media_type_id ORDER BY genre_id, media_type_id;

组的优先级/顺序与您列出它们的方式相同。您可以看到,在 GROUP BY 子句中切换 genre_id 和 composer 的顺序将产生完全不同的查询:

SELECT media_type_id, genre_id, COUNT(*) FROM tracks GROUP BY media_type_id, genre_id ORDER BY  media_type_id, genre_id;

注意,所有未列为 GROUP BY 参数的数据都需要应用聚合函数。

上一页
下一页