目录
1、为什么需要汇总数据
我们经常需要汇总数据而不用把它们实际检索出来,为此 SQL 提供了专门的函数。使用这些函数,SQL 查询可用于检索数据,以便分析和报表生成。这种类型的检索例子有:
- 确定表中行数(或者满足某个条件或包含某个特定值的行数)-- 比如统计订单数;
- 获得表中某些行的和 -- 比如求取订单总金额;
- 找出表列(或所有行或某些特定的行)的最大值、最小值、平均值。
上述例子都需要汇总表中的数据,而不需要实际数据本身。因此,返回实际表数据纯属浪费时间和处理资源(更不用说带宽了)。再说一遍,我们实际想要的是汇总信息。
2、聚集函数
为方便这种类型的检索,SQL 给出了 5 个聚集函数,见表 9-1。这些函数能进行上述检索。与前一章介绍的数据处理函数不同,SQL 的聚集函数在各种主要 SQL 实现中得到了相当一致的支持。
聚集函数(aggregate function):对某些行运行的函数,计算并返回一个值。
函数 | 说明 |
---|---|
AVG() | 返回某列的平均值 |
COUNT() | 返回某列的行数 |
MAX() | 返回某列的最大值,正常使用的是日期和数值;对于文本直接返回最后一行 |
MIN() | 返回某列的最小值,与MAX相反 |
SUM() | 返回某列之和 |
(1)AVG函数
对过滤后的所有行的指定列取平均值;获取多列的平均值需要使用多个AVG函数。
说明:NULL 值 :AVG()函数忽略列值为 NULL 的行。
-- 求所有产品平均价格
SELECT AVG(prod_price) AS avg_price
FROM products;
-- 求供应商是1002的所有产品均价,获取多列的平均值必须使用多个avg函数
SELECT AVG(prod_price) AS avg_price, MAX(prod_id) AS max_id
FROM products
WHERE vend_id = 1002; -- WHERE子句仅过滤出vend_id为1002的行
(2)COUNT函数
COUNT()函数进行计数。可利用 COUNT()确定表中行的数目或符合特定条件的行的数目。
COUNT()函数有两种使用方式:
- 使用 COUNT(*)对表中行的数目进行计数,不管表列中包含的是空值(NULL)还是非空值。
- 使用 COUNT(column)对特定列中具有值的行进行计数,忽略 NULL 值。
下面的例子返回 Customers 表中顾客的总数:
-- count统计行数,COUNT(*)统计该表所有行数,即使某些行的某列值是NULL
SELECT COUNT(*) -- 14行
FROM products;
SELECT COUNT(prod_price) -- 13行,因为有一个price为NULL
FROM products;
通过COUNT可以统计满足某条件的行数:比如我想统计拥有邮箱的顾客有多少个?
-- 统计拥有邮箱的顾客有多少个?
SELECT COUNT(cust_email)
FROM customers;
说明:NULL 值
如果指定列名,则 COUNT()函数会忽略指定列的值为空的行,但如果COUNT()函数中用的是星号(*),则不忽略。
(3)MAX和MIN函数
MAX()返回指定列中的最大值。MAX()要求指定列名,如下所示:
-- MAX函数,一般找日期和数值,对于文本直接返回该列排序后的最后一行
-- MIN函数与MAX函数相反
SELECT MAX(prod_id) AS max_id --
FROM products;
提示:对非数值数据使用 MAX()
虽然 MAX()一般用来找出最大的数值或日期值,但许多(并非所有)DBMS 允许将它用来返回任意列中的最大值,包括返回文本列中的最大值。在用于文本数据时,MAX()返回按该列排序后的最后一行。
说明:NULL 值 :MAX()函数忽略列值为 NULL 的行。
MIN()的功能正好与 MAX()功能相反,它返回指定列的最小值。与 MAX()一样,MIN()要求指定列名。
SELECT MIN(prod_price) AS min_price
FROM Products;
其中 MIN()返回 Products 表中最便宜物品的价格。
(4)SUM函数
SUM()用来返回指定列值的和(总计)。下面举一个例子,OrderItems 包含订单中实际的物品,每个物品有相应的数量。可如下检索所订购物品的总数(所有 quantity 值之和):
-- 统计订单号为20005的所有物品个数
SELECT SUM(quantity) AS prod_quantity
FROM orderitems
WHERE order_num = 20005;
SUM()也可以用来合计计算值。在下面的例子中,合计每项物品的item_price*quantity,得出总的订单金额:
-- SUM函数统计指定列值的和,比如统计某订单的所有产品总数和总价格
-- 利用标准的算术操作符,所有聚集函数都可用来执行多个列上的计算。
SELECT SUM(quantity) AS items_ordered, SUM(item_price * quantity) AS total_price
FROM OrderItems
WHERE order_num = 20005;
提示:在多个列上进行计算 :
利用标准的算术操作符,所有聚集函数都可用来执行多个列上的计算。
说明:NULL 值:SUM()函数忽略列值为 NULL 的行。
如果对字符串列或者日期列进行SUM呢?是不行哒~
-- 统计字符串之和是什么样子?
SELECT SUM(prod_id)
FROM orderitems;
-- 结果是0
-- 统计日期是什么样子?
SELECT SUM(order_date)
FROM orders;
-- 返回100254754000000,并不是时间戳哦,如果想验证的话可以使用FROM_UNIXTIME()函数
3、聚集不同值--DISTINCT
对所有行执行计算,指定 ALL 参数或不指定参数(因为 ALL 是默认行为)。
只包含不同的值,指定 DISTINCT 参数。
下面想通过COUNT函数通过orderitems表统计总共有多少个订单。
/*
ALL和DISTINCT参数在聚集函数中的作用
聚集不同值,上述中会对过滤后的数据中不为NULL的列值进行汇总,其实默认有一个ALL参数
对于相同的值可能不需要汇总,比如我想在orderitem中查看有多少个订单
聚集不同的值就需要使用DISTINCT参数
*/
SELECT COUNT(ALL order_num) -- 11个,有重复订单
FROM orderitems;
SELECT COUNT(DISTINCT order_num) -- 5个,无重复订单
FROM orderitems;
注意:DISTINCT 不能用于 COUNT(*)
如果指定列名,则 DISTINCT 只能用于 COUNT()。DISTINCT 不能用于 COUNT(*)。类似地,DISTINCT 必须使用列名,不能用于计算或表达式。
说明:其他聚集参数
除了这里介绍的 DISTINCT 和 ALL 参数,有的 DBMS 还支持其他参数,如支持对查询结果的子集进行计算的 TOP 和 TOP PERCENT。为了解具体的 DBMS 支持哪些参数,请参阅相应的文档。
4、组合聚集函数
组合聚集函数,就是SELECT语句可包含多个聚集函数,这里注意取的列名不要和原表重复。
SELECT COUNT(*) AS num_items,
MIN(prod_price) AS price_min,
MAX(prod_price) AS price_max,
AVG(DISTINCT prod_price) AS price_avg
FROM Products;
5、小结
- 有时候我们只需要某写数据的一些汇总或者统计信息,这时候不需要返回完整的数据,节省资源。
- SQL支持五类聚集函数用于汇总数据,分别是AVG、COUNT、MAX、MIN、SUM
- COUNT(*)代表统计行数
- 使用聚集函数时,指定列名后对NULL值不进行统计
- MAX可对数值、日期进行取最大值,对文本字符串只会返回最后一行,MIN相反
- 使用聚集函数时,可以利用标准操作符执行多个列上的计算操作,比如统计订单总金额
- 聚集函数默认参数ALL代表取所有值(包括相同),需要对不同值汇总要指定DISTINCT参数
- 组合聚集函数,就是SELECT语句可包含多个聚集函数