Andy Niu �����ĵ�

Andy Niu

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.