SQL-汇总数据

来自必知必会的实践

汇总数据

(不需要实际的行,只需要由这些行计算的结果,即汇总信息)

1. 聚集函数 ,高效,比客户端快得多
  • AVG():求单列的平均值(所有行或满足条件的行),忽略值为NULL的行。
    – 若想对多个列求平均,需要使用多个AVG()函数。
-- 查询产品表中所有产品的平均单价
SELECT AVG(prod_price) AS avg_price            -- 所有导出列都要命名
FROM Products;
-- 查询特定供应商提供产品的平均单价
SELECT AVG(prod_price) AS avg_price
FROM Products
WHERE vend_id='DLL01';

note:执行顺序:先从产品表中筛选出满足条件的行,再对这些行使用聚集函数,最后选出结果显示

  • COUNT() ,计数,确定满足条件的行的数目
    – COUNT(*):计算表中所有行数,无论是否为空,有主键也不可能为空=count(主键列)
    – COUNT(COLUMN):对特定列中非空的行计数,忽略NULL
-- 查询顾客表中顾客总数
SELECT COUNT(*) AS num_cust
FROM Customers;
-- 查询有电子邮件的顾客数
SELECT COUNT(cust_email) AS num_cust
FROM Customers;
  • MAX():返回指定列的最大值,可用于数值、日期、文本。用于文本时,返回按该列排序后的最后一行。忽略NULL
-- 查询产品表中最贵的产品价格
SELECT MAX(prod_price) AS max_price
FROM Products;
  • MIN():同MAX(),用于文本返回排序后的第一行

  • SUM():返回指定列的值和(总计)

-- 查询订单细节表中订单‘20005’订购的物品总数(所有quantity之和)
SELECT SUM(quantity) AS items_ordered
FROM OrderItems
WHERE order_num='20005';           -- 注意执行顺序,先筛选行,再应用聚集函数,最后显示

SUM()也可用来对计算值求和,不一定只对实际列值

-- 查询订单细节表中订单‘20005’订购的总金额(数量*单价再求和)
SELECT SUM(quantity*item_price) AS total_price
FROM OrderItems
WHERE order_num='20005'; 

– 若想达到去重效果,只计算不同的值,使用DISTINCT关键字,否则默认是ALL,其实还是DISTINCT+列保证了不重,聚集函数还是那个聚集函数

-- 查询特定供应商提供产品的不同价格的均值
SELECT AVG(DISTINCT prod_price) AS avg_price   -- 其实没啥用,就是使用DISTINCT筛选出不重的行
FROM Products
WHERE vend_id='DLL01';

– DISTINCT只用于列,必须指定列名,不能作用于计算或表达式
在这里插入图片描述

2. 组合聚集函数
-- 查询产品表的产品数、价格最值和均值
SELECT COUNT(*) AS num_items,
	   MIN(prod_price) AS min_price,    -- 注意指定别名时不能用实际的列名,会混淆
	   MAX(prod_price) AS max_price,
	   AVG(prod_price) AS avg_price
FROM Products;
3. 分组数据,使用GROUP BY ,HAVING子句 ,从而对每个组使用聚集函数分开计算
-- 查询不同供应商制造的产品个数
SELECT vend_id,COUNT(*) AS num_prods    -- 计算分组的组内个数,系统自动对每个组聚集
FROM Products
GROUP BY vend_id;      -- 按供应商排序并分组,这是分组列,最后select只能显示这一个实际列

note:分组语句中最终select显示的列只能是分组列+计算的聚集结果
– 分组可以嵌套,数据在最后指定的分组上(最细致的分组上)进行汇总
– 分组列必须是实际的列或有效的表达式(一堆值),不能是聚集函数(就一个值),并且GROUP BY中有的SELECT必须全都有,SELECT再加上聚集结果,即select=group by+聚集结果,不能有别的东西了
– 分组列不能是可变长的数据类型
– 分组列中若有NULL,也算一个分组
– 顺序:GROUP BY在WHERE子句后,ORDER BY前。因为先筛选满足条件的行,再细分组,最后对每组内的结果排序
– 不建议通过相对位置(1,2)指定列

4. 过滤分组 HAVING

– WHERE与HAVING的异同:都是过滤作用,WHERE在分组前过滤满足条件的行,HAVING在分组后过滤满足条件的分组,基于分组得到的聚集值来过滤
– WHERE是标准的行级过滤,HAVING要和GROUP BY结合

-- 查询至少有两个订单的所有顾客
SELECT cust_id,COUNT(*) AS orders
FROM Orders
GROUP BY cust_id
HAVING COUNT(*)>=2;   -- 过滤了分组

– 同时使用WHERE,HAVING

-- 查询具有两个以上产品并且价格至少为4的供应商
SELECT vend_id,COUNT(*) AS num_prods         -- 5.显示分组列和最后选出的组的聚集结果(作为新列)
FROM Products                 -- 1.从产品表
WHERE prod_price>=4           -- 2. 筛选出价格>=4的行
GROUP BY vend_id              -- 3.对这些行按供应商分组
HAVING COUNT(*)>=2            -- 4.对所有分组筛选出个数>=2的组
5. 分组和排序,分组后最好排下序

– 分组后的顺序不一定是我们想要的,需要重新排序,不能依赖GROUP BY 的排序

-- 查询订单细节表中订购了三个以上物品的订单与数目
SELECT order_num,COUNT(*) AS  items
FROM OrderItems
GROUP BY order_num
HAVING COUNT(*)>=3
ORDER BY items,order_num;
6. 执行顺序

在这里插入图片描述

发布了24 篇原创文章 · 获赞 6 · 访问量 1187

猜你喜欢

转载自blog.csdn.net/wbing96/article/details/103106901