对表进行聚合查询
聚合函数:通过sql对数据进行某种操作或者计算时需要使用函数
5个常见的函数:
cout:计算表中的记录数(行数)
sum:计算数值列中数据的合计值
avg:计算数值列中数据的平均值
max:求出数值列中数据的最大值
min:求出数值列中数据的最小值
例如:计算表中数据行数
select count(*)from Product;
计算null之外的数据的行数:
select count(purchase_price)from Product;
在计算数据行数时,purchase_price有两行数据为null,所以在计算时是不进行计算的
使用count(*)时会将所有行数进行计算
使用count(列名)时,计算时不包括数据为null的行数
该特性是count函数特有的,其他函数不能将*作为参数
计算列的合计值
select sum(sale_price) from Product;
select sum (purchase_price) from Product;
可以看到purchase_price列中是有两行数据为null的数据,那么前面学习的时候
“四则运算中如果存在 NULL,结果一定是 NULL,那此时进货单价
的合计值会不会也是 NULL 呢?”
通过查询结果可以看出,那么在进行查询时,即使包含null,也是会进行相加,因此不论多少个null都会被无视,这与等价为0并不相同。
计算平均值
avg函数与sum函数语法完全相同
SELECT AVG(sale_price)
FROM Product;
计算最大值和最小值:
SELECT MAX(sale_price), MIN(purchase_price)
FROM Product;
补充:
MAX/MIN函数几乎适用于所有数据类型的列。SUM/AVG函数只适用于数值类型的列。
使用聚合函数删除重复值(关键字 DISTINCT)
计算去掉重复值后数据的行数:
SELECT COUNT(DISTINCT product_name)
from Product;
先计算数据行数再删除重复数据的结果
SELECT DISTINCT COUNT(product_type)
FROM Product;
对表进行分组(GROUP BY)
GROUP BY子句:
语法结构:
select 列名1,列名2,列名3
from 表名
group by 列名1,列名2,列名3;
未使用group by 时:
select count(product_type)
from Product
输出结果:
使用group by:
SELECT product_type, COUNT(*)
FROM Product
GROUP BY product_type;
输出结果:
product_type | count
衣服 | 2
办公用品 | 2
厨房用具 | 4
未使用 GROUP BY 子句时,结果只有 1 行,而这次的结
果却是多行。这是因为不使用 GROUP BY 子句时,是将表中的所有数据作为一组来对待的。而使用 GROUP BY 子句时,会将表中的数据分为多个组进行处理。
group by就是像切分表的一把刀;
聚合键中包括null情况:
SELECT purchase_price, COUNT(*)
FROM Product
GROUP BY purchase_price;
输出:
聚合键中包含NULL时,在结果中会以“不确定”行(空行)的形式表现出来。
使用where子句时group by的执行结果:
SELECT <列名1>, <列名2>, <列名3>, ……
FROM <表名>
WHERE
GROUP BY <列名1>, <列名2>, <列名3>, ……;
使用where子句进行汇总处理时,会先根据where子句指定的条件进行过滤,然后在进行汇总处理。
Group by 和 where 并用时,select 语句的执行顺序如下列所示:
from -》 where -》group by -》 select
常见错误:
在select 子句中书写多余的列
实际上使用聚合函数时,select 子句中只能存在以下三种元素:
常数、聚合函数、group by 子句中指定的列名(也就是聚合键)
在SELECT子句中书写聚合键之外的列名会发生错误
SELECT product_name, purchase_price, COUNT(*)
FROM Product
GROUP BY purchase_price;
执行结果(使用PostgreSQL的情况)
列"product,product_name"必须包含在GROUP BY子句之中,或者必须在聚合
函数内使用
行 1: SELECT product_name, purchase_price, COUNT(*)
不过,只有MySQL认同这种语法,所以能够执行,不会发生错误(在多列候补中只要有一列满足要求就可以了)。但是MySQL以外的DBMS都不支持这样的语法
使用GROUP BY子句时,SELECT子句中不能出现聚合键之外的列名。
在group by 子句中写了列的别名
SELECT product_type AS pt, COUNT(*)
FROM Product
GROUP BY pt;
是 SQL 语句在 DBMS内部的执行顺序造成的 select 子句在group by 子句后执行
PostgreSQL 执行上述 SQL 语句并不会发生错误,而会得到如下结果。但是这样的写法在其他 DBMS 中并非通用的。
pt | count
衣服 | 2
办公用品 | 2
厨房用具 | 4
group by 子句的结果能排序吗?
随机的
GROUP BY子句结果的显示是无序的。
在where子句中只用聚合函数
例如:
按照商品名称统计数据行数
select product_type,count(*)
from Product
group by product_type;
如果我们想要取出恰好包含 2 行数据的组该怎么办呢
select product_type,count()
from Product
where count() =2*
group by product_type;*
这样的sql在执行的时候会报错
ERROR: 不能在WHERE子句中使用聚合
行 3: WHERE COUNT(*) = 2
补充:
DISTINCT 和 GROUP BY
distinct 和group by 可以实现相同功能
select distinct product_type
from Product
select product_type
from Product
group by product_type;
这两个执行结果是相同的。除此之外,distinct和group by 进行查询时,还会把null作为一行结果进行返回,对多列进行使用,也是会返回相同结果。
想要删除选择结果中的重复数据记录时,使用distinct ,在想要计算汇总结果时使用group by 。