语法顺序:select [select 选项] 字段列表[字段别名]/* from 数据源 [where条件子句] [group by子句] [having 子句] [order by子句] [limit 子句];
having子句
与where子句一样,是进行条件判断的(having读内存,可以使用字段别名;where读磁盘,不可以使用字段别名)
having能够使用字段别名
(having可以做where的所有事,而where却不能做having的所有事)
-- 求出所有班级人数大于等于2的学生人数(having子句不能放group by前面,where可以)
select c_id,count(*) from my_student group by c_id having count(*)>=2;
select c_id,count(*) from my_student where count(*)>=2 group by c_id; -- 报错
having可以使用字段别名、where不可以
-- 优化(起别名)
select c_id,count(*) as total from my_student group by c_id having total>=2;
select c_id,count(*) as total from my_student where total>=2 group by c_id; -- 报错
-- having子句进行条件查询
select name as 名字, number as 学号 from my_student having 名字 like '张%';
select name as 名字, number as 学号 from my_student where 名字 like '张%'; -- 报错 找不到名字这个字段
order by子句
基本语法:order by 字段名 [asc|desc](asc默认升序,desc降序)
-- 排序
select * from my_student group by c_id;-- 每个班级只取一个
select * from my_student order by c_id;-- 保留所有记录,并按班级进行排序
-- 多字段排序:先班级排序 后性别排序(设置同一个班,女生在前,男生在后)
select * from my_student order by c_id,sex desc;
limit子句
方案一:只用来限制长度,即数据量:limit 数据量;
-- 查询学生:前两个(典型的限制计量数)(从哪开始每页多少条)
select * from my_student limit 2;
方案二:限制起始位置,限制数量:limit 起始位置,长度;
limit offset,length;
length:每页显示的数据量,基本不变
offset = (页码-1)*每页显示量
select * from my_student limit 0,2; -- 记录是从0开始编号
select * from my_student limit 4,2; -- 记录是从4开始编号
select * from my_student limit 5,2; -- 记录是从5开始编号
交叉-内连接
连接查询(join)分类:内连接、外连接、自然连接、交叉连接
使用方式:左表 join 右表
-- 更改ID为班级表的第一列
alter table my_class change id id int first;-- alter修改-table表-my_class表名-change更改-id-名字id-int类型-first位置;
交叉连接(cross join)(没什么意义)
基本语法:左表 cross join 右表; -- 等价于:from 左表,右表;
-- 交叉连接
select * from my_student cross join my_class; -- my_student cross join my_class是数据源
内连接([inner] join)
基本语法:左表 [inner] join 右表 on 左表.字段=右表.字段;
on表示连接条件
-- 内连接(可以没有连接条件,也就是on之后的,如果没有,系统会保留所有的东西——笛卡尔积)
select * from my_student inner join my_class on my_student.c_id=my_class.id; -- 完整写法
select * from my_student inner join my_class on c_id=my_class.id; -- 可以如此简写,省略my_student,只有学生表有c_id
select * from my_student inner join my_class on c_id=id; -- 不可如此简写,my_student与my_class两张表都有id字段
-- 字段和表别名(c_代表班级)
select s.*,c.name as c_name,c.room -- 字段的别名
from my_student as s inner join my_class as c -- 表别名
on s.c_id=c.id; -- my_student as s inner join my_class as c on s.c_id=c.id是数据源
-- 把学生表id为5的记录的c_id设置为NULL
update my_student set c_id=null where id=5;
-- 不写on条件,就是笛卡尔积
select s.*,c.name as c_name,c.room
from my_student as s inner join my_class as c;
-- where代替on(where一个一个拉,on用索引找到直接拉)
select s.*,c.name as c_name,c.room -- 字段的别名
from my_student as s inner join my_class as c -- 表别名
where s.c_id=c.id;