分组数据
数据分组
使用分组可以将数据分为多个逻辑组,对每个组进行聚集计算。
创建分组
分组是使用 SELECT 语句的 GROUP BY 子句建立的。
SELECT vend_id, COUNT(*) AS num_prods
FROM Products
GROUP BY vend_id;
上面的 SELECT 语句指定了两个列: vend_id 包含产品供应商的 ID,num_prods 为计算字段(用 COUNT(*) 函数建立)。 GROUP BY 子句指示DBMS按 vend_id 排序并分组数据。
- GROUP BY 子句必须出现在 WHERE 子句之后, ORDER BY 子句之前。
- 如果分组列中包含具有 NULL 值的行,则 NULL 将作为一个分组返回。如果列中有多行 NULL 值,它们将分为一组。
- 除聚集计算语句外, SELECT 语句中的每一列都必须在 GROUP BY 子句中给出。
- GROUP BY 子句可以包含任意数目的列,因而可以对分组进行嵌套,更细致地进行数据分组。
- 如果在 GROUP BY 子句中嵌套了分组,数据将在最后指定的分组上进行汇总。换句话说,在建立分组时,指定的所有列都一起计算(所以不能从个别的列取回数据)。
过滤分组
HAVING 非常类似于 WHERE 。事实上,目前为止所学过的所有类型的 WHERE 子句都可以用 HAVING 来替代。唯一的差别是, WHERE过滤行,而 HAVING 过滤分组。
SELECT cust_id, COUNT(*) AS orders
FROM Orders
GROUP BY cust_id
HAVING COUNT(*) >= 2;
HAVING 和 WHERE 的差别
这里有另一种理解方法, WHERE 在数据分组前进行过滤, HAVING 在数据分组后进行过滤。这是一个重要的区别, WHERE 排除的行不包括在分组中。这可能会改变计算值,从而影响 HAVING 子句中基于这些值过滤掉的分组。
SELECT vend_id, COUNT(*) AS num_prods
FROM Products
WHERE prod_price >= 4
GROUP BY vend_id
HAVING COUNT(*) >= 2;
WHERE 子句过滤所有 prod_price 至少为 4 的行,然后按 vend_id分组数据, HAVING 子句过滤计数为 2或 2以上的分组。
分组和排序
Order by 和 Group by 的区别
SELECT order_num, COUNT(*) AS items
FROM OrderItems
GROUP BY order_num
HAVING COUNT(*) >= 3
ORDER BY items, order_num;