汇总统计数据--SQL中聚集函数的使用

目录

1、为什么需要汇总数据

2、聚集函数

(1)AVG函数

(2)COUNT函数

(3)MAX和MIN函数

(4)SUM函数

3、聚集不同值--DISTINCT

4、组合聚集函数

5、小结


1、为什么需要汇总数据

我们经常需要汇总数据而不用把它们实际检索出来,为此 SQL 提供了专门的函数。使用这些函数,SQL 查询可用于检索数据,以便分析和报表生成。这种类型的检索例子有:

  • 确定表中行数(或者满足某个条件或包含某个特定值的行数)-- 比如统计订单数
  • 获得表中某些行的和 -- 比如求取订单总金额
  • 找出表列(或所有行或某些特定的行)的最大值、最小值、平均值

上述例子都需要汇总表中的数据,而不需要实际数据本身。因此,返回实际表数据纯属浪费时间和处理资源(更不用说带宽了)。再说一遍,我们实际想要的是汇总信息

2、聚集函数

为方便这种类型的检索,SQL 给出了 5 个聚集函数,见表 9-1。这些函数能进行上述检索。与前一章介绍的数据处理函数不同,SQL****的聚集函数在各种主要 SQL 实现中得到了相当一致的支持

聚集函数(aggregate function): 对某些行运行的函数,计算并返回一个值。

函数 说明
AVG() 返回某列的平均值
COUNT() 返回某列的行数
MAX() 返回某列的最大值,正常使用的是日期和数值;对于文本直接返回最后一行
MIN() 返回某列的最小值,与MAX相反
SUM() 返回某列之和

(1)AVG函数

对过滤后的所有行的指定列取平均值;获取多列的平均值需要使用多个AVG函数。

说明:NULL 值 : AVG()函数忽略列值为 NULL 的行。

sql 复制代码
-- 求所有产品平均价格
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 表中顾客的总数:

sql 复制代码
-- count统计行数,COUNT(*)统计该表所有行数,即使某些行的某列值是NULL
SELECT COUNT(*)      -- 14行
FROM products;

SELECT COUNT(prod_price)      -- 13行,因为有一个price为NULL
FROM products;

通过COUNT可以统计满足某条件的行数:比如我想统计拥有邮箱的顾客有多少个?

sql 复制代码
-- 统计拥有邮箱的顾客有多少个?
SELECT COUNT(cust_email)
FROM customers;

说明:NULL 值

如果指定列名,则 COUNT()函数会忽略指定列的值为空的行,但如果COUNT()函数中用的是星号(*),则不忽略。

(3)MAX和MIN函数

MAX()返回指定列中的最大值。MAX()要求指定列名,如下所示:

sql 复制代码
-- MAX函数,一般找日期和数值,对于文本直接返回该列排序后的最后一行
-- MIN函数与MAX函数相反
SELECT MAX(prod_id) AS max_id            -- 
FROM products;

提示:对非数值数据使用 MAX()

虽然 MAX()一般用来找出最大的数值或日期值,但许多(并非所有)DBMS 允许将它用来返回任意列中的最大值,包括返回文本列中的最大值。在用于文本数据时,MAX()返回按该列排序后的最后一行。
说明:NULL 值 : MAX()函数忽略列值为 NULL 的行。

MIN()的功能正好与 MAX()功能相反,它返回指定列的最小值。与 MAX()一样,MIN()要求指定列名。

sql 复制代码
SELECT MIN(prod_price) AS min_price 
FROM Products;

其中 MIN()返回 Products 表中最便宜物品的价格。

(4)SUM函数

SUM()用来返回指定列值的和(总计)。下面举一个例子,OrderItems 包含订单中实际的物品,每个物品有相应的数量。可如下检索所订购物品的总数(所有 quantity 值之和):

sql 复制代码
-- 统计订单号为20005的所有物品个数
SELECT SUM(quantity) AS prod_quantity
FROM orderitems
WHERE order_num = 20005;

SUM()也可以用来合计计算值。在下面的例子中,合计每项物品的item_price*quantity,得出总的订单金额:

sql 复制代码
-- SUM函数统计指定列值的和,比如统计某订单的所有产品总数和总价格
-- 利用标准的算术操作符,所有聚集函数都可用来执行多个列上的计算。
SELECT SUM(quantity) AS items_ordered, SUM(item_price * quantity) AS total_price
FROM OrderItems 
WHERE order_num = 20005;

提示:在多个列上进行计算 :

利用标准的算术操作符,所有聚集函数都可用来执行多个列上的计算。

说明:NULL 值: SUM()函数忽略列值为 NULL 的行。

如果对字符串列或者日期列进行SUM呢?是不行哒~

sql 复制代码
-- 统计字符串之和是什么样子?
SELECT SUM(prod_id)
FROM orderitems;
-- 结果是0


-- 统计日期是什么样子?
SELECT SUM(order_date)
FROM orders;
-- 返回100254754000000,并不是时间戳哦,如果想验证的话可以使用FROM_UNIXTIME()函数

3、聚集不同值--DISTINCT

对所有行执行计算,指定 ALL 参数或不指定参数(因为 ALL 是默认行为)。

只包含不同的值,指定 DISTINCT 参数。

下面想通过COUNT函数通过orderitems表统计总共有多少个订单。

sql 复制代码
/*
	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语句可包含多个聚集函数,这里注意取的列名不要和原表重复。

sql 复制代码
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、小结

  1. 有时候我们只需要某写数据的一些汇总或者统计信息,这时候不需要返回完整的数据,节省资源。
  2. SQL支持五类聚集函数用于汇总数据,分别是AVG、COUNT、MAX、MIN、SUM
  3. COUNT(*)代表统计行数
  4. 使用聚集函数时,指定列名后对NULL值不进行统计
  5. MAX可对数值、日期进行取最大值,对文本字符串只会返回最后一行,MIN相反
  6. 使用聚集函数时,可以利用标准操作符执行多个列上的计算操作,比如统计订单总金额
  7. 聚集函数默认参数ALL代表取所有值(包括相同),需要对不同值汇总要指定DISTINCT参数
  8. 组合聚集函数,就是SELECT语句可包含多个聚集函数
相关推荐
老邓计算机毕设5 分钟前
SSM智慧社区家政服务系统80q7o(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·ssm 框架
松涛和鸣1 小时前
72、IMX6ULL驱动实战:设备树(DTS/DTB)+ GPIO子系统+Platform总线
linux·服务器·arm开发·数据库·单片机
likangbinlxa1 小时前
【Oracle11g SQL详解】UPDATE 和 DELETE 操作的正确使用
数据库·sql
r i c k2 小时前
数据库系统学习笔记
数据库·笔记·学习
野犬寒鸦2 小时前
从零起步学习JVM || 第一章:类加载器与双亲委派机制模型详解
java·jvm·数据库·后端·学习
IvorySQL3 小时前
PostgreSQL 分区表的 ALTER TABLE 语句执行机制解析
数据库·postgresql·开源
·云扬·3 小时前
MySQL 8.0 Redo Log 归档与禁用实战指南
android·数据库·mysql
IT邦德3 小时前
Oracle 26ai DataGuard 搭建(RAC到单机)
数据库·oracle
惊讶的猫3 小时前
redis分片集群
数据库·redis·缓存·分片集群·海量数据存储·高并发写
不爱缺氧i4 小时前
完全卸载MariaDB
数据库·mariadb