目录
一、聚合查询
1.1 什么是聚合查询
聚合查询的结果不是来自表记录的直接结果,而是将查询记录进行“合计(聚合)”之后的结果
比如在一个班级表中,有学生姓名,性别和年纪的记录,通过聚合查询可以得到一共有多少个男生,多少个女生等
select 聚合函数(...)from 表 where 条件;
1) 先通过where进行记录的筛选
2)再把筛选出来的记录,按照聚合函数的要求进行聚合
1.2 MySql下的聚合函数
count(...) :统计符合条件的记录一共有多少条
sum(...) :进行求和统计
avg(...) :进行求平均值统计
max(...) :进行求最大值统计
min(...) :进行求最小值统计
sum、avg、max、min只能聚合数值类型的字段或者表达式
null不参与聚合
1.3 分组聚合
1) 分组聚合是先通过where条件进行记录的筛选
2) 然后根据分组凭证group by xxx,将符合条件的记录分为不同的组
3) 最后根据各组,分别进行各自的聚合
select 聚合函数(...)from 表 where 条件x group by 条件y;
注意事项
1)进行分组聚合的时候,select后面只能跟:聚合函数或者分组凭证
2)一条sql中可以进行多次分组聚合,多次分组谁先谁后没有区别
1.4 分组之后,还能进行一次过滤
select 聚合函数(...)from 表 where 条件x group by 条件y having z条件;
where和having都是在对记录做筛选,但是!!!where是发生在聚合之前,having是聚合之后
具体顺序
1)where进行过滤
2)再用group by 进行分组
3)进行聚合
4)最后再用having对聚合后的数据进行一次过滤
二、联表查询
从多张表中同时查询
-- 进行联表查询的两种方式
-- 如果光进行联表查询,没有其他信息,得到的结果是笛卡尔积的关系
select * from classes, students;
select * from classes join students;
联表查询需要指定至少一个联表条件,例如班级表中的一班和学生表中某学生是一班的,这就是一个联表条件,完全没有联表条件的联表查询是没有意义的,得到的结果是笛卡尔积的关系
-- 指定联表条件进行联表查询
-- 这里联表条件中不能光写 cid,因为 cid 在此处有歧义(ambiguous)
select * from classes, students where classes.cid = students.cid;
select * from classes join students where classes.cid = students.cid;
select * from classes join students on classes.cid = students.cid;
可以给表名起别名,方便些SQL
select * from classes as c, students as s where c.cid = s.cid;
select * from classes c, students s where c.cid = s.cid;
select * from classes c join students s on c.cid = s.cid;
2.1 内联(inner join)
上面的例子就是内联,通过两张表的某些相同数据作为联表条件进行联合
2.2 外联(outer join)
左外联(left outer join): 简写为left join
from A 表 left join B 表 :左表的所有数据都要显示,右表中若无和左表对应的数据,则用null代替
右外联(right outer join): 简写为right join
from A 表 right join B 表 :右表的所有数据都要显示,左表中若无和右表对应的数据,则用null代替
全外联(full outer join)
左右表的所有数据都要显示,若另一张表无对应数据,则补null
2.3 自联
将一张表看做两张表进行联表查询,同时,必须给另一张表起别名用以表示是两张表在进行联表查询
三、子查询/嵌套查询
在一个查询中嵌套另一个查询
3.1 出现在from条件后的嵌套查询
无论是何种select,查询出来的结果一定是m行n列,其中m>=0,n>=1
我们完全可以把查询结果也看做一张表,继续对这个表进行查询
select xxx from (select yyy from xx 表 where ...) as tem where....
子查询出现在 from 后边的时候,必须起别名,同时必须用小括号括起来
在这个基础上可以多次嵌套
3.2 出现在where后面的嵌套查询
子查询的结果为
1)1行1列
select * from classes
where cid = (
select cid from students where sid = 's1'
);
-- 等价于
select * from classes where cid = 'c1';
//cid为班级号,sid为学生号
2)1行n列 n > 1
select * from students where (sid, cid) = (
select sid, cid from students where sname = '小蓝'
);
-- 等价于,注意是 and
select * from students where sid = 's2' and cid = 'c1';
3)m行1列
IN(...)
select * from students where sname in (
select sname from students
);
-- 等价于
select * from students where sname in ('小红', '小蓝', '小粉', '小绿', '小白');
ANY(...)
select * from classes where cid != any(
select distinct cid from students
);
-- 等价于
select * from classes where cid != 'c1' or cid != 'c2' or cid != 'c3' or cid != 'c100';
ALL(...)
select * from classes where cid != all(
select distinct cid from students
);
-- 等价于
select * from classes where cid != 'c1' and cid != 'c2' and cid != 'c3' and cid != 'c100';
4)exist(...) 或者 not exist(...)
select * from classes c where exists (
select * from students s where c.cid = s.cid
);
上面这个例子其实用联表查询直接就能得出结果
select * from classes c join students s on c.cid = s.cid;
先进行外部查询,然后将结果带入到内部进行内部查询