Andy Niu Help
1.0.0.0
|
变量 | |
汇总数据 | |
分组数据 | |
使用子查询 | |
详细描述
变量说明
使用子查询 |
1、所谓子查询,就是嵌套在其他查询中查询,经常使用的场景,如下: mysql> select name,teaid from stu where teaid in (1,2); +----------+-------+ | name | teaid | +----------+-------+ | Andy | 1 | | Bill | 2 | | Caroline | 1 | | David | 2 | | Eric | 1 | | Andy | 2 | | David | 1 | | Eric | 2 | +----------+-------+ 8 rows in set mysql> select name,teaid from stu where teaid in (select id from tea where name='Mr Li' or name ='Mr Zhang'); +----------+-------+ | name | teaid | +----------+-------+ | Andy | 1 | | Bill | 2 | | Caroline | 1 | | David | 2 | | Eric | 1 | | Andy | 2 | | David | 1 | | Eric | 2 | +----------+-------+ 8 rows in set 2、作为计算字段使用子查询,统计每个老师的学生个数,如下: mysql> select name,(select count(1) from stu where stu.teaid = tea.id) as StuNum from tea; +----------+--------+ | name | StuNum | +----------+--------+ | Mr Li | 4 | | Mr Zhang | 4 | | Mrs Niu | 0 | +----------+--------+ 3 rows in set 执行过程如下: 投影name,对于tea表的每一个id取值,传给子查询,统计学生个数,也就是说,子查询执行3次。 相对于第一种子查询,这种子查询叫做相关子查询,因为这种子查询涉及到外部查询。 3、对于group by,也可以使用相关子查询来实现,如下: mysql> select name,avg(age) from stu group by name; +----------+----------+ | name | avg(age) | +----------+----------+ | Andy | 15.0000 | | Bill | 17.0000 | | Caroline | 17.0000 | | David | 11.5000 | | Eric | 19.0000 | +----------+----------+ 5 rows in set mysql> select distinct name,(select avg(age) from stu as A where A.name = stu.name) as AvgAge from stu; +----------+---------+ | name | AvgAge | +----------+---------+ | Andy | 15.0000 | | Bill | 17.0000 | | Caroline | 17.0000 | | David | 11.5000 | | Eric | 19.0000 | +----------+---------+ 5 rows in set 执行过程:对于每一个distinct name,传给相关子查询,用于统计平均值。
分组数据 |
1、汇总数据是对满足条件的所有记录进行聚集。考虑下面的需求,将记录根据某个字段(某些字段)分成多个逻辑组, 再对每个逻辑组进行聚集计算,怎么办? 2、使用group by 进行分组,如下: select name,avg(age) from stu group by name; 3、考虑下面两个语句的区别: select name from stu where id>2; select name,avg(age) from stu where id>2 group by name; 前一个语句,先选择,再投影,select字段name 后一个语句,先选择,然后进行逻辑分组,得到多个逻辑分组,每个分组里面,一个name关联一组id和一组age。 对每个分组进行投影,select字段name,对其它字段进行聚集计算。 特别注意:对于分组,select的内容(也就是投影的内容)一般包括分组的字段,和其它字段的汇总。 当然,也可以select不是分组的字段,语法没错。但是,这样做并没有意义。 因为进行逻辑分组之后,对于其他字段,一个分组中往往包含多个数据,进行select,只会获取其中的第一个数据, 这个数据往往没有意义,对其它字段的一组数据进行聚集计算才有意义。 4、如果过滤分组,比如检查age的平均值,怎么办? 使用 having,这个时候的过滤条件往往是 其它字段的聚集函数,如下: select name,max(age) from stu group by name having max(age)>17; 5、select的字句顺序和执行顺序 select xxx from xxx where xxx group by xxx having xxx order by xxx limit xxx; 执行顺序: a、首先根据where进行行级选择 b、group by 进行分组 c、通过having 进行分组过滤 d、然后order by xxx limit e、最后投影 思考:为什么投影是最后进行的操作? 因为行过滤,分组过滤,有可能是根据其它的字段进行过滤,如果先投影就没法再进行过滤了。
汇总数据 |
1、有时候我们需要汇总数据,而不是查询记录。Mysql提供5个聚集函数。 count max min avg sum 2、示例如下: mysql> select count(age) from stu; +------------+ | count(age) | +------------+ | 5 | +------------+ 1 row in set mysql> select max(age) from stu; +----------+ | max(age) | +----------+ | 19 | +----------+ 1 row in set 3、考虑下面的需求,某一个字段,对于不同的值进行聚集,怎么办? 使用distinct,如下: select sum(distinct age) from stu; 注意:函数max和min,可以对不同的值进行聚集,但这样做并没有意义。因为去除相同的值,并不影响最大值和最小值。 4、如果同时求出平均值和最大值,怎么办? 使用组合聚集函数,也就是对多个聚集函数组合,如下: mysql> select count(age),avg(age),max(age) from stu; +------------+----------+----------+ | count(age) | avg(age) | max(age) | +------------+----------+----------+ | 5 | 15.8000 | 19 | +------------+----------+----------+ 1 row in set mysql> select count(age),avg(distinct age),max(age) from stu; +------------+-------------------+----------+ | count(age) | avg(distinct age) | max(age) | +------------+-------------------+----------+ | 5 | 15.5000 | 19 | +------------+-------------------+----------+ 1 row in set
Copyright (c) 2015~2016, Andy Niu @All rights reserved. By Andy Niu Edit.