Skip to content

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
-- 显示身高最高的2名女性的数据
select * from students where gender=2 order by high desc limit 2;

连接查询

当查询结果的列来源于多张表时,需要将多张表连接成一个大的数据集,再选择合适的列返回。

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 的嵌套叫做子查询。

-- 查询最高男生的信息
select * from students where high = (select max(high) from students) and gender=1;
-- 查询山东省所有的市
select * from areas where pid = (select aid from areas where atitle="山东省");