一、创建分组
上面所讲的语句都是建立在表的所有数据或匹配特定的where子句的数据上进行的。是否能够进行分组,在进行汇总计算哪儿?例如:要想返回每个供应商提供的产品数目怎么办?
分组是在select语句的group by子句中建立的,如下:
select vend_id,count(*) as num_prods from products group by vend_id;
上面语句使用group by子句对vend_id排序并分组数据,也就是按供应商编码进行分组,把相同的编码进行合并,并且求出其产品个数。
group by 子句指示mysql分组数据,然后对每个组而不是整个结果集进行聚集。
二、group by 注意事项
1、group by 子句可以包含任意数目的列。
2、如果在该子句中嵌套了分组,指定的所有列都一起进行计算。
3、该子句选中列出的每个列都必须是检索列或者有效的表达式(不能是聚集函数)。如果在select中使用表达式,则必须在group by 子句中指定相同的表达式,不能使用别名。
4、除聚集计算语句外,select语句中的每个列都必须在group by 子句中给出。
5、如果分组列中具有NULL,则NULL将作为一个分组返回。如果列中有多行NULL值,他们将分为一组。
6、group by 必须出现在where子句之后,order by子句之前。
其中rollup关键字的作用很明显,它可以显示出不进行分组所有产品个数(之前没进行分组的不显示)。如下:
select vend_id ,count(*) as num from products group by vend_id with rollup;
三、过滤分组
mysql还可以过滤分组,我们不能使用where子句,它仅仅是对行进行操作,而且在数据分组前进行过滤,不能多分组数据操作。
我们只能使用having子句,他能用来过滤分组。它在数据分组后进行过滤。
having支持所有的where操作符。如下:
select cust_id,count(*) as orders from orders group by cust_id having count(*)>=2;
以上语句描述的是找出两个以上订单的那些分组。
select vend_id,count(*) as num_prods from products where prod_price>=10 group by vend_id having count(*)>=2
以上语句表达的是列出具有2个以上、价格10以上的产品供应商。
*:聚集函数可以在select的检索中,可以在分组之后的having过滤中,但是不可以在where中;
四、分组和排序
group by 和 order by具有不同的用处
group by 每次并不是以分组的顺序输出,而order by却能提供顺序。
select order_num,sum(quantity*item_price) as ordertotal from orderitems group by order_num having sum(qquantity*itemprice)>=50;
以上并不排序,如果需要排序,需要在后面加上order by ordertotal