[mysql] Mysql數據分組GROUP BY 和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子句不行。

因為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 ORDER BY ordertotal;

結果是:
+-----------+------------+
| 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
---------------------
轉自:https://blog.csdn.net/liuchunming033/article/details/47279003  僅供個人學習,有改動


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM