Mysql之查询

120 阅读6分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情

DQL

  • 所有的查询操作都用Select
  • 简单的查询,复杂的都可以做
  • 数据库中最核心的语言,最重要的语句
  • 使用最频繁的语句

语法

select [all | distinct]
{* | table.* | [table.field1[as alias1][,table.field2[as alias2]][,...]]}
from table_name [as table_alias]
[left | right | inner join table_name2] --联合查询
[where ...] --指定结果需要满足的条件
[group by ...] --指定结果按照那几个字段来分组
[having ...] --过滤分组的记录必须满足的次要条件
[order by ...] --指定查询记录按一个或多个条件排序
[limit {[offset,]row_count | row_countoffset offset}]; --指定查询的记录从哪条到哪条

注:[]代表可选,{}代表必选

指定查询字段

查询

语法:

select 字段 ,... from 表名

样例:

--查询全部的学生
select * from `student`;
​
--查询指定字段
select `sudentno`, `studentname` from student;
​
--别名,给结果取一个名字,用as。也可以给字段和表取别名
select `studentno` as 学号, `studentname` as 学生姓名 from student as s;
​
--函数 concat(a, b),拼接字符串
select concat('姓名:', studentname) as 新名字 from student;

去重 (distinct)

作用:去除select 查询出来的结果中重复的数据,重复的数据只显示一条

--查询有那些同学参加了考试,去重
select distinct `studentno` from result;

如果没有 distinct 则默认为 all

数据库的列(表达式)

语法:

select 表达式 from 表
--查询系统版本
select version();
​
--用来计算
select 100*3 - 1 as 计算结果;
​
--查询自增的步长(变量)
select @@auto_increment_increment;

数据库中的表达式有:文本值,列,null,函数,计算表达式,系统变量...

where 条件子句

查询结合逻辑运算符

作用:检索数据中符合条件的值

--查询考试成绩在95-100之间,and 和 && 是相同
select studentno, `studentresult` from result
where studentresult >= 95 and studentresult <= 100;
​
--模糊查询(区间)
select studentno, `studentresult` from result
where studentresult between 95 and 100;
​
--除了100号学生之外的同学的成绩,not 和 != 和 <> 相同
select studentno,`studentresult` from result
where studentno != 1000;
--where not studentno = 1000;

模糊查询:比较运算符

运算符语法描述
is nulla is null如果操作符为null,结果为真
is not nulla is not null如果操作符不为null,结果为真
betweena between b and c如果a在b和c之间,结果为真
likea like b如果a匹配b,结果为真
ina in (a1, a2, a3...)假设a在括号里的某一个值,结果为真

样例:

1、like 运算符

--查询姓李的同学,like结合 %(匹配从0个到任意个的任意字符串),_(匹配一个任意字符)
select `studentno`, `studentname` from `student`
where studentname like '李%';
​
--查询姓李的同学,名字后面只有一个字的
select `studentno`, `studentname` from `student`
where studentname like '李_';
​
--查询名字中间有嘉字的同学
select `studentno`, `studentname` from `student`
where studentname like '%嘉%';
​
--如果查询的字符串本身就有通配符,则用 escape'换码字符'
select `studentno`, `studentname` from `student`
where studentname like '李_' escape'';   --将_通配符转义

2、in 运算符

--查询1001,1002,1003号学员
select `studentno`, `studentname` from `student`
where studentno in(1001, 1002, 1003);

3、is /not null 运算符

--查询地址为空的学生
select `studentno`, `studentname` from `student`
where address = '' or address is null;

--查询有出生日期的学生
select `studentno`, `studentname` from `student`
where `borndate` is not null;

联表查询

join 对比

1、inner join

--查询参加了考试的同学(学号,姓名,科目编号,分数)
select s.studentno, studentname, subjectno, studentresult
from student as s
inner join result as r
on s.studentno = r.studentno;

2、right join

select student.studentno, studentname, subjectno, studentresult
from student
right join result
on student.studentno = result.studentno;

3、left join

select student.studentno, studentname, subjectno, studentresult
from student
left join result
on student.studentno = result.studentno;

三者对比:

操作描述
inner join如果表中至少有一个匹配,就返回
left join会从左表中返回所有的值,即使右表中没有匹配
right join会从右表中返回所有的值,即使左表中没有匹配

如果不能理解可以看看这个 左右内外连接

语法:

join (连接的表)  on (判断的条件)  连接查询
where  等值查询

自连接

自己的表和自己的表连接,核心:一张表拆为两张一样的表即可

样例:

父类

categoryidcategoryname
2信息技术
3软件开发
5美术设计

子类

pidcategoryidcategoryname
34数据库
28办公信息
36web开发
57ps设计

操作代码:

--查询父子信息:把一张表看成两个一样的表
select a.`categoryname` as `父栏目`, b.`categoryname` as `子栏目`
from `category` as a, `category` as b
where a.`categoryid` = b.`pid`;

操作结果:

父类子类
信息技术办公信息
软件开发数据库
软件开发web开发
美术设计ps技术

分页和排序

排序

排序:升序(ASC),降序(DESC)

--查询的结果根据成绩降序排序
select s.`studentno`, `studentname`, `subjectname`, `studentresult`
from student
inner join `result`
on student.studentno = result.studentno
inner join `subject`
on result.`subjectno` = subject.`subjectno`
where subjectname = '数据结构-1'
order by studentresult asc;

分页

为什么要分页?

缓解数据库压力,体验更好

limit使用语法:

limit(查询起始下标, pagesize)

样例:

--每页只显示五条数据
select s.`studentno`, `studentname`, `subjectname`, `studentresult`
from student
inner join `result`
on student.studentno = result.studentno
inner join `subject`
on result.`subjectno` = subject.`subjectno`
where subjectname = '数据结构-1'
order by studentresult asc
limit 0, 5;

/*
第N页的limit设定: (n - 1) * pagesize, pagesize
pagesize是页面大小(页面显示的数据个数)
n表示当前页面
数据总数/页面大小 = 总页数,向上取整
*/

子查询(嵌套)

where 后面可以用计算出来的值

本质:在where中嵌套一个子查询语句

--查询数据库结构-1的所有考试结果(学号,科目编号,成绩),降序排列
--方式一:使用连接查询
select `studentno`, r.`subjectno`, `studentresult`
from `result` r
inner join `subject` sub
on r.subjectno = sub.subjectno
where subjectname = '数据库结构-1'
order by studentresult desc
--方式二:使用子查询
select `studentno`, `subjectno`, `studentresult`
from `result`
where subjectno = (
	select studentno
    from `subject`
    where subjectname = '数据库结构-1'
)
order by studentresult desc

分组和过滤

语法:

group by 条件

样例:

--查询不同课程的平均分,用分组
select subjectname, avg(studentresult)
from result r
inner join subject s
on r.subjectno = s.subjectno
group by r.subjectno

集合查询

集合操作主要包括并操作(union)、交操作(intersect)和差操作(except)

并操作

就是将多个查询结果合并起来,默认去除重复元组,不去除用:union all

--查询选了课程1和课程2的学生学号
select sno from sc
where cno = 1
union
select sno from sc
where cno = 2;

交操作

相当于使用 and 运算符

--查询计算机系中年龄小于等于18岁的学生
select * from student
where sdept = 'cs'
intersect
select * from student
where sage <= 18;

差操作

第一个查询的结果去除第二个查询的结果

--查询计算机系中年龄小于等于18岁的学生
select * from student
where sdept = 'cs'
except
select * from student
where sage > 18;