Mysql数据分组GROUPBY和HAVING,与WHERE组合使⽤理解分组,可以这样:对GROUP BY⼦句后⾯跟随的列名进⾏分组,然后对每⼀个分组⽽不是整个表进⾏操作。
举例:在产品表中,检索每⼀个供应商提供的商品的数量。
mysql> SELECT vend_id,COUNT(*) AS num_prods FROM products GROUP BY vend_id;
结果:
+---------+-----------+
| vend_id | num_prods |
+---------+-----------+
| 1001 | 3 |
| 1002 | 2 |
| 1003 | 7 |
| 1005 | 2 |
+---------+-----------+
4 rows in set (0.01 sec)
分析:
⾸先根据vend_id进⾏分组,然后对每⼀个分组在进⾏COUNT聚集。当检索的⽬的是针对每⼀个记录进⾏检索的时候,想到⽤GROUP BY,例如这⾥是针对每⼀个供应商。
GROUP BY的规定:
1、GROUP BY 后⾯可以包含多个列,这就是嵌套。
2、如果GROUP BY进⾏了嵌套,数据将在最后⼀个分组上进⾏汇总。
3、GROUP BY⼦句中列出来的每个列必须是检索列或有效的表达式(但不能是聚集函数),如果在SELECT中使⽤了表达式,则必须在GROUP BY⼦句中指定相同的表达式。不能使⽤别名。
4、除了聚集语句外,SELECT语句中的每⼀个列都必须在GROUP BY⼦句中给出。
5、如果分组列中具有NULL值,则NULL将作为⼀个分组返回。如果列中有多个NULL,它们将作为⼀
个分组返回。
6、GROUP BY⼦句必须在WHERE ⼦句之后,ORDER BY ⼦句之前。
过滤分组结果
我们知道WHERE ⼦句⽤于过滤结果,但是对于分组的过滤WHERE⼦句不⾏。
groupby分组因为WHERE⼦句,是针对⾏的过滤。要对分组结果进⾏过滤,必须使⽤HAVING⼦句,HAVING⼦句能针对分组的结果进⾏过滤。
举例:
在订单表中,检索出具有两个以上订单的客户id以及订单数量。
分析:
在这个检索需求中,需要先根据客户id进⾏分组,然后过滤出订单数量⼤于2的分组。
mysql> SELECT cust_id,COUNT(*) AS orders FROM orders GROUP BY cust_id HAVING orders>=2;
结果:
+---------+--------+
| cust_id | orders |
+---------+--------+
| 10001 | 2 |
+---------+--------+
1 row in set (0.00 sec)
与WHERE组合使⽤(先⽤WHERE过滤)
有的时候,GROUP BY和WHERE⼦句也要组合使⽤。⽐如:在产品表中检索出能提供2个以上商品,并且价格⾼于10的供应商。
分析:
⾸先,检索的是供应商,因此SELECT⼦句应该是SELECT vend_id
其次,产品表中,有价格这⼀列,因此对于价格⾼于10的条件的过滤要使⽤WHERE⼦句。SELECT vend_id FROM prodcuts WHERE prod_price>=10.
接着,对vend_id进⾏分组,这样就可以得到每个vend_id的价格⾼于10的商品数量,GROUP BY放到WHERE⼦句后。SELECT vend_id FROM prodcuts WHERE prod_price>=10 GROUP BY vend_id.
最后,对分组的结果过滤,过滤出2个以上商品的分组
mysql> SELECT vend_id,COUNT(*) AS num_prods FROM products WHERE prod_price>=10 GROUP BY vend_id HAVING COUNT(*)>=2;
结果:
+---------+-----------+
| vend_id | num_prods |
+---------+-----------+
| 1003 | 4 |
| 1005 | 2 |
+---------+-----------+
2 rows in set (0.00 sec)
对分组结果进⾏排序
在订单明细表中,检索出订单总价格⾼于等于50的订单号以及订单总价格
mysql> SELECT order_num,SUM(quantity*item_price) AS ordertotal FROM orderitems GROUP BY order_num HAVING SUM(quantity*item_price)>=50 OR
结果是:
+-----------+------------+
| order_num | ordertotal |
+-----------+------------+
| 20006 | 55.00 |
| 20008 | 125.00 |
| 20005 | 149.87 |
| 20007 | 1000.00 |
+-----------+------------+
4 rows in set (0.08 sec)
SELECT ⼦句的顺序
SELECT
FROM
WHERE GROUP BY HAVING ORDER BY LIMIT
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论