分组是在SELECT BY子句中建立的。
SELECT vend_id,COUNT(*) AS num_prods
FROM products
GROUP BY vend_id;
vend_id num_prods
1001 3
1002 2
1003 7
上面语句指定了两个列,vend_id包含产品供应商的id,num_prods为计算字段(产品数量)。GROUP BY 子句指示MySQL按vend_id排序并分组数据。这导致每个vend_id而不是整个表计算num_prods一次。
从输出中可以看到,供应商1001有三个产品,供应商1002有两个产品,供应商1003有7个产品。
GROUP BY子句必须出现在WHERE 子句之后,ORDER BY子句之前。
如果分组中具有NULL值,则NULL将作为一个分组返回。如果列中有多行NULL值,它们将分为一组。
除了能用GROUP BY分组数据外,MySQL还允许过滤分组,规定包括哪些分组,排除哪些分组。例如,可能想要列出至少有两个订单的所有顾客,为了得出这种数据,必须基于完整的分组而不是个别的行进行过滤。在这个例子中,WHERE不能完成任务,因为WHERE过滤指定的是行而不是分组。事实上,WHERE没有分组的概念。
可以使用HAVING子句。
它过滤两个以上订单的那些分组。
SELECT cust_id,COUNT(*) AS orders
FROM orders
GROUP BY cust_id
HAVING COUNT(*)>=2;
HAVING和WHERE的区别:WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤。
上述语句,使它返回过去12个月内具有两个以上订单的顾客,为达到这一点,可以增加一条WHERE子句。
过滤出过去12个月内下过的订单,然后再增加HAVING子句过滤出具有两个以上订单的分组。
SELECT vend_id,COUNT(*) AS num_prods
FROM products
WHERE prod_price>=10
GROUP BY vend_id
HAVING COUNT(*)>=2;
它列出具有两个以上、价格≥10的产品的供应商,然后按照vend_id进行分组。
一般在使用GROUP BY子句时,应该也给出ORDER BY子句。这是保证数据正确排序的唯一方法。千万不要仅依赖GROUP BY排序数据。
SELECT order_num,SUM(quantity*item_price) AS ordertotal
FROM orderitems
GROUP BY order_num
HAVING SUM(quantity*item_price)>=50
ORDER BY ordertotal;
GROUP BY子句用来按订单号(order_num列)分组数据,以便SUM()函数能够返回总计订单价格。HAVING子句过滤数据,使得只返回总计订单价格大于等于50的订单。最后,用ORDER BY子句排序输出。