1.创建分组
分组是使用SELECT语句的GROUP BY 子句建立的。
在使用GROUP BY 子句前,需要知道一些重要的规定。
- GROUP BY 子句可以包含任意数目的列,因而可以对分组进行嵌套,更细致地进行数据分组。
- 如果在GROUP BY子句 中嵌套了分组,数据将在最后指定的分组上进行汇总。换句话说,在建立分组时,指定的所有列都一起计算(所有不能从个别的列取回数据)。
- GROUP BY 子句 中列出的每一列都必须是检索列或有效的表达式(但不能是聚集函数)。如果是SELECT中使用表达式,则必须在GROUP BY 子句中指定相同的表达式。不能使用别名。
- 大多数SQL实现不允许GROUP BY 列带有长度可变的数据类型。
- 除聚集计算语句外,SELECT语句中的每一列都必须在GROUP BY 子句中给出。
- 如果分组列中包含具有NULL值的行,则NULL将作为一个分组返回。如果列中有多行NULL值,它们将分为一组。
- GROUP BY 子句必须出现在WHERE 子句之后,ORDER BY 子句之前。
SQL
SELECT vend_id, COUNT(*) AS num_prods
FROM Products
GROUP BY vend_id
"SELECT `主流派` , COUNT(*) AS StyleCount
FROM blockbusters GROUP BY `主流派`"
2.过滤分组
除了能用GROUP BY 分组数据外,SQL还允许过滤分组,规定包括哪些分组,排除哪些分组。
例如,你可能想要列出至少有两个订单的所有顾客。为此,必须基于完整的分组而不是个别的行进行过滤。
我们可以使用HAVING,HAVING非常类似WHERE。
事实上,目前为止所学过的所有类型的WHERE子句都可以用HAVING来替代。
唯一的差别是,WHERE过滤行,而HAVING过滤分组。
SQL
SELECT cust_id,COUNT(*) AS orders
FROM Products
WHERE prod_price>=4
GROUP BY vend_id
HAVING COUNT(*) >=2;
"SELECT `主流派`,COUNT(*) AS 主流派数量
FROM blockbusters
WHERE `年份`>=2016
GROUP BY `主流派`
HAVING COUNT(*) >=2"
PowerShell
说明:HAVING和WHERE的差别
这里有另一种理解方法,WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤。
这是一个重要的区别,WHERE排除的行不包括在分组中。
这可能会改变计算值,从而影响HAVING子句中基于这些值过滤掉的分组。
说明:使用HAVING和WHERE
HAVING与WHERE非常类似,如果不指定GROUP BY,则大多数DBMS会同等对待它们。
不过,你自己要能区分这一点。
使用HAVING时应该结合GROUP BY子句,而WHERE 子句用于标准的行级过滤。
3.分组和排序
分组:GROUP BY
排序:ORDER BY
ORDER BY 和 GROUP BY 的区别
ORDER BY | GROUP BY | |
对产生的输出排序 | 对行分组,但输出可能不是分组的顺序 | |
任意列都可以使用(甚至非选择的列也可以使用) | 只可能使用选择列或表达式列,而且必须使用每个选择列表达式 | |
不一定需要 | 如果与聚集函数一起使用列(或表达式),则必须使用。 |
4.SELECT 子句顺序
SELECT 子句及其顺序
子句 | 说明 | 是否必须使用 |
SELECT | 要返回的列或表达式 | 是 |
FROM | 从中检索数据的表 | 仅在从表选择数据时使用 |
WHERE | 行级过滤 | 否 |
GROUP BY | 分组说明 | 仅在按组计算聚集时使用 |
HAVING | 组级过滤 | 否 |
ORDER BY | 输出排序顺序 | 否 |