MySQL 查询语句
介绍了 SQL 命令中的查询语句。
简单查询
select [distinct] [表名.]列名 [as 别名],... from 表名 [as 别名];
-- distinct 可以去重
-- 如果给表起了别名,使用"表名.列名" 的时候表名就必须使用别名
条件查询
select 列名,... from 表名 where 条件;
-- 比较运算符 > < = != <> >= <=
-- 逻辑运算符 and or not
select * from students where age<18 and id>3;
-- 模糊查询
-- 列名 like 含%或_的字符串(% 替换零个或多个,_ 替换1个)
select * from students where name not like "小_%";
-- 列名 rlike 正则表达式
select * from students where name rlike "^[小大].*";
-- 范围查询
-- 列名 [not] in (值1, 值2, ...)
select * from students where age in (8, 12, 21);
-- 列名 [not] between 值1 and 值2
select * from students where age not between 4 and 23;
-- 空判断(is [not] null)
select * from students where high is null;
排序
select 列名 from 表名 [where 条件] order by 字段1 [asc/desc], 字段2 [asc/desc], ...
-- asc 升序排序;desc 降序排序。默认asc
-- 按字段1->字段2->...优先级来排序
select * from students order by high desc, age asc, id desc;
聚合函数
- count:总数
- max/min:最大/小值
- avg:平均值
- sum:求和
- round:四舍五入
-- 查询男性人数
select count(*) as 男性人数 from students where gender="男";
-- 查询最大年龄
select max(age) from students;
-- 查询平均身高,保留1位小数
select round(avg(high), 1) from students;
分组
分组与聚合密切相关
-- 分组通过group by
select 项目1, 项目2, ... from 表名 [where 条件] group by 列名;
-- 对每一分组显示对应内容group_concat(内容1,内容2,...)
-- 括号中的内容i可以是列名可以是字符串
select gender,group_concat(name, " ", age),avg(age) from students group by gender;
-- 对分组进行条件判断用 having 条件
-- 注:where 进行的条件判断是对数据库中的每行数据,而 having 针对的是每一分组
select gender,group_concat(name),avg(age) from students group by gender having avg(age)>14;
分页
当数据太多时,可通过分页操作限制查询出来的个数(limit 总是放在最后)。
- limit n:显示前 n 行数据
- limit m, n:显示从第 m 个(从0开始)开始的 n 个数据
-- 每页5条数据
-- 查看第1页数据的命令
select * from students limit 0,5
-- 查看第2页数据的命令
select * from students limit 5,5
连接查询
当查询结果的列来源于多张表时,需要将多张表连接成一个大的数据集,再选择合适的列返回。
MySQL 支持三种连接查询:
- 内连接查询(inner):查询到的结果为两个表都匹配到的数据
- 右连接查询(right):查询的结果为两个表匹配到的数据,右表特有而左表不存在的数据使用null填充
- 左连接查询(left):与右连接查询相反。
命令格式为
select 列名,... from 左表 inner/right/left join 右表 on 条件
-- 对于内连接,如果条件不满足,不显示
-- 左连接与右连接合称外连接,条件如果无法满足,对于左连接,左表中的数据显示,右表对应的项以null填充
为说明连接查询,在该数据库中构造一个名为 classes 的表,有 id 与 name 两列,并插入几条信息。
-- 按班级名称升序排序,班级内以学号排序,将所有可以找到班级信息的学生的信息及其班级名称输出
select s.* , c.name as class_name from students as s inner join classes as c on s.cls_id=c.id order by c.name, s.id;
-- 查询没有对应班级信息的学生
select s.* from students as s left join classes as c on s.cls_id=c.id where c.id is null;
自关联
设计如下三个表:
- 省信息:provinces(pro_id, pro_name)
- 市信息:citys(city_id, city_name, pro_id)
- 区县信息:district(dis_id, dis_name, city_id)
上列三个表完全可以合成一张表(pro_id, city_id, dis_id 没有重复),这张表里 pid 链向的还是自己,所以叫做自关联。
新表列名 | 省信息 | 市信息 | 区县信息 |
---|---|---|---|
aid | pro_id | city_id | dis_id |
atitle | pro_name | city_name | dis_name |
pid | null | pro_id | city_id |
如下是在该表上进行的一些查询操作
-- 查询所有的省份
select * from areas where pid is null;
-- 查询山东省所有的市
select city.aid, city.atitle from areas as city inner join areas as province on city.pid=province.aid where province.atitle="山东省";
简单子查询
select 的嵌套叫做子查询。