读书笔记--SQL必知必会10--分组数据
2016-12-25 15:38
316 查看
10.1 数据分组
使用分组可以将数据分为多个逻辑组,对每个组进行聚集计算。10.2 创建分组
使用SELECT语句的GROUP BY子句建立分组。GROUP BY子句必须出现在WHERE之后,ORDER BY子句之前。
GROUP BY子句可以包含任意数目的列,可以对分组进行嵌套。
如果GUOUP BY子句中嵌套了分组,数据将在最后指定的分组上进行汇总。
GUOUP BY子句中的列必须是实际有效的检索列或表达式,不能使用别名。
除聚集计算语句外,SELECT语句中的每一列都必须在GROUP BY子句中给出。
一行或多行NULL值,将作为一个分组返回。
某些DBMS允许根据SELECT列表中的相对位置指定列,但不建议使用,容易导致编辑SQL语句时出错。
MariaDB [sqlbzbh]> SELECT * FROM Products; +---------+---------+---------------------+------------+-----------------------------------------------------------------------+ | prod_id | vend_id | prod_name | prod_price | prod_desc | +---------+---------+---------------------+------------+-----------------------------------------------------------------------+ | BNBG01 | DLL01 | Fish bean bag toy | 3.49 | Fish bean bag toy, complete with bean bag worms with which to feed it | | BNBG02 | DLL01 | Bird bean bag toy | 3.49 | Bird bean bag toy, eggs are not included | | BNBG03 | DLL01 | Rabbit bean bag toy | 3.49 | Rabbit bean bag toy, comes with bean bag carrots | | BR01 | BRS01 | 8 inch teddy bear | 5.99 | 8 inch teddy bear, comes with cap and jacket | | BR02 | BRS01 | 12 inch teddy bear | 8.99 | 12 inch teddy bear, comes with cap and jacket | | BR03 | BRS01 | 18 inch teddy bear | 11.99 | 18 inch teddy bear, comes with cap and jacket | | RGAN01 | DLL01 | Raggedy Ann | 4.99 | 18 inch Raggedy Ann doll | | RYL01 | FNG01 | King doll | 9.49 | 12 inch king doll with royal garments and crown | | RYL02 | FNG01 | Queen doll | 9.49 | 12 inch queen doll with royal garments and crown | +---------+---------+---------------------+------------+-----------------------------------------------------------------------+ 9 rows in set (0.00 sec) MariaDB [sqlbzbh]> MariaDB [sqlbzbh]> MariaDB [sqlbzbh]> SELECT vend_id, COUNT(*) AS num_prods FROM Products GROUP BY vend_id; +---------+-----------+ | vend_id | num_prods | +---------+-----------+ | BRS01 | 3 | | DLL01 | 4 | | FNG01 | 2 | +---------+-----------+ 3 rows in set (0.00 sec) MariaDB [sqlbzbh]> MariaDB [sqlbzbh]> SELECT vend_id, COUNT(*) AS num_prods FROM Products GROUP BY 1; +---------+-----------+ | vend_id | num_prods | +---------+-----------+ | BRS01 | 3 | | DLL01 | 4 | | FNG01 | 2 | +---------+-----------+ 3 rows in set (0.00 sec) MariaDB [sqlbzbh]>
10.3 过滤分组
使用HAVING子句可以过滤分组。相比之下,WHERE子句过滤指定的是行而不是分组。也可以理解为: WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤。
HAVING子句支持所有WHERE操作符,也就是说有关WHERE的句法都适用于HAVING,只是关键字可能有差别。
MariaDB [sqlbzbh]> SELECT * FROM Orders; +-----------+---------------------+------------+ | order_num | order_date | cust_id | +-----------+---------------------+------------+ | 20005 | 2012-05-01 00:00:00 | 1000000001 | | 20006 | 2012-01-12 00:00:00 | 1000000003 | | 20007 | 2012-01-30 00:00:00 | 1000000004 | | 20008 | 2012-02-03 00:00:00 | 1000000005 | | 20009 | 2012-02-08 00:00:00 | 1000000001 | +-----------+---------------------+------------+ 5 rows in set (0.00 sec) MariaDB [sqlbzbh]> MariaDB [sqlbzbh]> SELECT cust_id, COUNT(*) AS orders FROM Orders GROUP BY cust_id; +------------+--------+ | cust_id | orders | +------------+--------+ | 1000000001 | 2 | | 1000000003 | 1 | | 1000000004 | 1 | | 1000000005 | 1 | +------------+--------+ 4 rows in set (0.00 sec) MariaDB [sqlbzbh]> MariaDB [sqlbzbh]> SELECT cust_id, COUNT(*) AS orders FROM Orders GROUP BY cust_id HAVING COUNT(*) >=2; +------------+--------+ | cust_id | orders | +------------+--------+ | 1000000001 | 2 | +------------+--------+ 1 row in set (0.00 sec) MariaDB [sqlbzbh]>
同时使用WHERE子句和HAVING子句
MariaDB [sqlbzbh]> SELECT * FROM Products; +---------+---------+---------------------+------------+-----------------------------------------------------------------------+ | prod_id | vend_id | prod_name | prod_price | prod_desc | +---------+---------+---------------------+------------+-----------------------------------------------------------------------+ | BNBG01 | DLL01 | Fish bean bag toy | 3.49 | Fish bean bag toy, complete with bean bag worms with which to feed it | | BNBG02 | DLL01 | Bird bean bag toy | 3.49 | Bird bean bag toy, eggs are not included | | BNBG03 | DLL01 | Rabbit bean bag toy | 3.49 | Rabbit bean bag toy, comes with bean bag carrots | | BR01 | BRS01 | 8 inch teddy bear | 5.99 | 8 inch teddy bear, comes with cap and jacket | | BR02 | BRS01 | 12 inch teddy bear | 8.99 | 12 inch teddy bear, comes with cap and jacket | | BR03 | BRS01 | 18 inch teddy bear | 11.99 | 18 inch teddy bear, comes with cap and jacket | | RGAN01 | DLL01 | Raggedy Ann | 4.99 | 18 inch Raggedy Ann doll | | RYL01 | FNG01 | King doll | 9.49 | 12 inch king doll with royal garments and crown | | RYL02 | FNG01 | Queen doll | 9.49 | 12 inch queen doll with royal garments and crown | +---------+---------+---------------------+------------+-----------------------------------------------------------------------+ 9 rows in set (0.00 sec) MariaDB [sqlbzbh]> MariaDB [sqlbzbh]> MariaDB [sqlbzbh]> SELECT vend_id, COUNT(*) AS num_prods FROM Products GROUP BY vend_id HAVING COUNT(*) >=2; +---------+-----------+ | vend_id | num_prods | +---------+-----------+ | BRS01 | 3 | | DLL01 | 4 | | FNG01 | 2 | +---------+-----------+ 3 rows in set (0.00 sec) MariaDB [sqlbzbh]> MariaDB [sqlbzbh]> MariaDB [sqlbzbh]> SELECT vend_id, COUNT(*) AS num_prods FROM Products WHERE prod_price >= 4 GROUP BY vend_id HAVING COUNT(*) >=2; +---------+-----------+ | vend_id | num_prods | +---------+-----------+ | BRS01 | 3 | | FNG01 | 2 | +---------+-----------+ 2 rows in set (0.00 sec) MariaDB [sqlbzbh]>
10.4 分组和排序
对比GROUP BY 与 ORDER BYGROUP BY | OREDR BY |
---|---|
输出可能不是分组的顺序 | 对产生的输出排序 |
只能使用选择列或表达式列,而且必须使用每个选择列表达式 | 任意列都可以使用,包括非选择列 |
必须使用与聚集函数一起的列或表达式 | 不一定需要 |
一般在使用GROUP BY子句的同时也使用ORDER BY子句,保证数据正确排序,满足实际需要。
MariaDB [sqlbzbh]> SELECT * FROM OrderItems; +-----------+------------+---------+----------+------------+ | order_num | order_item | prod_id | quantity | item_price | +-----------+------------+---------+----------+------------+ | 20005 | 1 | BR01 | 100 | 5.49 | | 20005 | 2 | BR03 | 100 | 10.99 | | 20006 | 1 | BR01 | 20 | 5.99 | | 20006 | 2 | BR02 | 10 | 8.99 | | 20006 | 3 | BR03 | 10 | 11.99 | | 20007 | 1 | BR03 | 50 | 11.49 | | 20007 | 2 | BNBG01 | 100 | 2.99 | | 20007 | 3 | BNBG02 | 100 | 2.99 | | 20007 | 4 | BNBG03 | 100 | 2.99 | | 20007 | 5 | RGAN01 | 50 | 4.49 | | 20008 | 1 | RGAN01 | 5 | 4.99 | | 20008 | 2 | BR03 | 5 | 11.99 | | 20008 | 3 | BNBG01 | 10 | 3.49 | | 20008 | 4 | BNBG02 | 10 | 3.49 | | 20008 | 5 | BNBG03 | 10 | 3.49 | | 20009 | 1 | BNBG01 | 250 | 2.49 | | 20009 | 2 | BNBG02 | 250 | 2.49 | | 20009 | 3 | BNBG03 | 250 | 2.49 | +-----------+------------+---------+----------+------------+ 18 rows in set (0.00 sec) MariaDB [sqlbzbh]> MariaDB [sqlbzbh]> SELECT order_num, COUNT(*) AS items FROM OrderItems GROUP BY order_num; +-----------+-------+ | order_num | items | +-----------+-------+ | 20005 | 2 | | 20006 | 3 | | 20007 | 5 | | 20008 | 5 | | 20009 | 3 | +-----------+-------+ 5 rows in set (0.00 sec) MariaDB [sqlbzbh]> MariaDB [sqlbzbh]> SELECT order_num, COUNT(*) AS items FROM OrderItems GROUP BY order_num HAVING COUNT(*) >= 3; +-----------+-------+ | order_num | items | +-----------+-------+ | 20006 | 3 | | 20007 | 5 | | 20008 | 5 | | 20009 | 3 | +-----------+-------+ 4 rows in set (0.00 sec) MariaDB [sqlbzbh]> MariaDB [sqlbzbh]> SELECT order_num, COUNT(*) AS items FROM OrderItems GROUP BY order_num HAVING COUNT(*) >= 3 ORDER BY items, order_num; +-----------+-------+ | order_num | items | +-----------+-------+ | 20006 | 3 | | 20009 | 3 | | 20007 | 5 | | 20008 | 5 | +-----------+-------+ 4 rows in set (0.00 sec) MariaDB [sqlbzbh]> MariaDB [sqlbzbh]> SELECT order_num, COUNT(*) AS items FROM OrderItems GROUP BY order_num HAVING COUNT(*) >= 3 ORDER BY items; +-----------+-------+ | order_num | items | +-----------+-------+ | 20006 | 3 | | 20009 | 3 | | 20007 | 5 | | 20008 | 5 | +-----------+-------+ 4 rows in set (0.01 sec) MariaDB [sqlbzbh]>
10.5 SELECT子句顺序
在SELECT语句中使用子句时,必须遵循的次序。子句 | 说明 | 是否必须使用 |
---|---|---|
SELECT | 要返回的列或表达式 | 是 |
FROM | 从表中检索数据 | 仅在从表选择数据时使用 |
WHERE | 行过滤 | 否 |
GROUP BY | 分组 | 仅在按组计算聚集时使用 |
HAVING | 组过滤 | 否 |
ORDER BY | 输出排序 | 否 |
相关文章推荐
- 读书笔记--SQL必知必会10--分组数据
- 机器学习实战 - 读书笔记(10) - 利用K-均值聚类算法对未标注数据分组
- 《利用python进行数据分析》读书笔记--第九章 数据聚合与分组运算(二)
- 读书笔记--SQL必知必会02--检索数据
- 读书笔记--SQL必知必会04--过滤数据
- 读书笔记--SQL必知必会16--更新和删除数据
- 读书笔记--SQL必知必会15--插入数据
- SQL数据进行排序、分组、统计10技巧
- 读书笔记--SQL必知必会02--检索数据
- 背水一战 Windows 10 (51) - 控件(集合类): ItemsControl - 项模板选择器, 数据分组
- mysql按照每天分组查询数据结果排序不是从1到31而是1后接10
- 读书笔记--SQL必知必会04--过滤数据
- 读书笔记--SQL必知必会03--排序检索数据
- 读书笔记--SQL必知必会03--排序检索数据
- 读书笔记--SQL必知必会09--汇总数据
- 《利用python进行数据分析》读书笔记--第九章 数据聚合与分组运算(一)
- SQL笔记(10)_第十章 数据排序与分组
- 读书笔记--SQL必知必会05--高级数据过滤
- 读书笔记--SQL必知必会09--汇总数据
- 读书笔记--SQL必知必会16--更新和删除数据