mysql必知必会第12~14章笔记

#第12章: 汇总数据

聚集函数

mysql提供一些聚集函数用来汇总数据,比如返回表中一个有多少行,表中某列的的平均值,最大值等.
mysql聚集函数:

函数 说明
MAX(列名) 返回该列的最大值,如果是字符串返回按字典排序最后的那个,忽略NULL值
MIN(列名) 返回该列的最小值,如果是字符串返回按字典顺序第一个,忽略NULL值
SUM(列名) 返回该列的总和,如果是字符串类型,语法可以通过但返回0,忽略NULL值
AVG(列名) 返回该列的平均值,如果是字符串类型,语法可以通过但返回0,忽略NULL值
COUNT(*) 返回表的总行数,不忽略NULL值
COUNT(列名) 返回表的总行数,如果该列为NULL,则忽略

例:返回orderitems表中的总行数,order_price的平均值,最大值,最小值,平均值和总和

SELECT COUNT(*) AS row_num ,
AVG(item_price) AS item_price_avg,
MAX(item_price) AS item_price_max,
MIN(item_price) AS item_price_max,
SUM(item_price) AS item_price_sum
FROM orderitems;

结果:

+---------+----------------+----------------+----------------+----------------+
| row_num | item_price_avg | item_price_max | item_price_max | item_price_sum |
+---------+----------------+----------------+----------------+----------------+
|      11 |      12.904545 |          55.00 |           2.50 |         141.95 |
+---------+----------------+----------------+----------------+----------------+

DISTINCT在聚集函数中的使用

mysql5及以后版本支持在聚集函数中加入DISTINCT关键字来对聚集函数中的列去重
products表中vend_id=1003的数据:

+---------+---------+----------------+------------+-------------------------------------------------+
| prod_id | vend_id | prod_name      | prod_price | prod_desc                                       |
+---------+---------+----------------+------------+-------------------------------------------------+
| FC      |    1003 | Carrots        |       2.50 | Carrots (rabbit hunting season only)            |
| TNT1    |    1003 | TNT (1 stick)  |       2.50 | TNT, red, single stick                          |
| SLING   |    1003 | Sling          |       4.49 | Sling, one size fits all                        |
| FB      |    1003 | Bird seed      |      10.00 | Large bag (suitable for road runners)           |
| TNT2    |    1003 | TNT (5 sticks) |      10.00 | TNT, red, pack of 10 sticks                     |
| DTNTR   |    1003 | Detonator      |      13.00 | Detonator (plunger powered), fuses not included |
| SAFE    |    1003 | Safe           |      50.00 | Safe with combination lock                      |
+---------+---------+----------------+------------+-------------------------------------------------+

可以看到,prod_price中的数据有重复的,下面的查询语句中将把表中prod_price重复的行只算一次,也就是去重再求平均值

SELECT AVG(DISTINCT prod_price) AS avg_price 
FROM products 
WHERE vend_id=1003; 

结果:

+-----------+
| avg_price |
+-----------+
| 15.998000 |
+-----------+

注意:在聚集函数中,DISTINCT不能用于COUNT(*)聚集函数,否则会报错,COUNT(列名) 函数可以.

第13章:分组数据

创建分组

分组由GROUP BY 子句来完成 看一个例子:

SELECT vend_id, COUNT(*) AS num_prods
FROM products GROUP BY vend_id; 

上面的语句将products表中的数据按vend_id 列进行分组,返回vend_id的值和总数

+---------+-----------+
| vend_id | num_prods |
+---------+-----------+
|    1001 |         3 |
|    1002 |         2 |
|    1003 |         7 |
|    1005 |         2 |
+---------+-----------+

vend_id=1001的行有3行
vend_id=1002的行有2行 ,以此类推...

GROUP BY子句的注意事项

  1. GROUP BY 子句可以包含任意数目的列,这说明GROUP BY 子句可以对分组进行嵌套,为数据分组提供更细致的控制
  2. 如果GROUP BY 子句中嵌套了分组,数据将在最后规定的分组进行汇总.换句话说,在建立分组是,指定的列都一起计算(不能从各别的列取回数据)
  3. GROUP BY 子句后面列出的每个列必须是检索列或有效的表达式(但不能是聚集函数),如果在SELECT 中使用表达式,如果还想在GROUP BY 子句中使用,应该写相同的表达式,不能使用别名
  4. 除聚集计算外,SELECT语句中的每个类必须在GRUOP BY 子句中给出
  5. 如果分组列中有NULL值,将作为NULL返回,如果列中有多行NULL值,NULL将归为一组返回
  6. 如果WHERE ,GROUP BY ,ORDER BY 子句共同出现,GROUP BY子句要在WHERE 之后,ORDER BY之前

WITH ROLLUP关键字

使用WITH ROLLUP关键字可以得到分组的汇总数据
不用WITH ROLLUP

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 |
+---------+-----------+

使用WITH ROLLUP

SELECT vend_id, COUNT(*) AS num_prods
  FROM products
  GROUP BY vend_id WITH ROLLUP;

结果

+---------+-----------+
| vend_id | num_prods |
+---------+-----------+
|    1001 |         3 |
|    1002 |         2 |
|    1003 |         7 |
|    1005 |         2 |
|    NULL |        14 |
+---------+-----------+

3+2+7+2=14

HAVING 过滤分组

用HAVING放在GROUP BY 的后面来过滤分组

SELECT vend_id , COUNT(*) AS  `count` 
FROM products
GROUP BY vend_id HAVING `count` >2;

上面语句的意思是:将products表按vend_id分组后将count(*)>2的行检索出来
结果:

+---------+-------+
| vend_id | count |
+---------+-------+
|    1001 |     3 |
|    1003 |     7 |
+---------+-------+

可以看到count的值都是大于2的
当然WHERE 和 HAVING 可以同时存在,可以认为WHERE在分组前进行过滤,HAVING在分组后进行过滤

SELECT vend_id ,COUNT(*) AS `count` 
FROM products 
WHERE prod_price>5.0 
GROUP BY vend_id HAVING `count`>2;

上面语句的意思是:在products表中把prod_price>5.0的行按vend_id进行分组,在将分组中count>2的行检索出来

+---------+-------+
| vend_id | count |
+---------+-------+
|    1001 |     3 |
|    1003 |     4 |
+---------+-------+

#第14章:子查询 mysql4.1引入了子查询,如果想使用子查询,mysql版本要在myslq4.1及更高

利用子查询进行过滤

SELECT * FROM products  WHERE prod_price >
								(SELECT AVG(prod_price) FROM products);

上面语句的意思是:在products表中将prod_price大于prod_price平均值的行检索出来

SELECT * FROM products WHERE prod_price IN
								(SELECT MAX(prod_price) FROM products GROUP BY vend_id);

上面语句的意思是:将products表按vend_id分组后,每个组prod_price最大的行的所有信息检索出来

作为计算字段使用子查询

SELECT cust_name,cust_state , (SELECT COUNT(*) FROM orders 
												WHERE orders.cust_id=customers.cust_id) AS orders
							   FROM 
									customers ORDER BY cust_name;

上面语句的意思是:将在orders表查询符合orders表cust_id等于customers表的cust_id的总行数作为一个字段,同 cust_name,cust_state 一并返回并按cust_name 升序排列

全部评论

相关推荐

神哥了不得:放平心态,再找找看吧,主要现在计算机也变卷了,然后就比较看学历了,之前高中毕业你技术强,都能找到工作的
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务