9.高级的Select语句的使用(重点)

1.去重查询

根据之前创建的数据库表和数据,我们提一个需求,查询所有参加了考试的学生的学号

select `studentno` from `result`	--查询所有有成绩的学生的学号 

9.高级的Select语句的使用(重点)
根据结果,可以看出,数据有大量的重复,因此我们可以使用distinct对数据进行去重查询。

SELECT DISTINCT `studentno` from `result`;

9.高级的Select语句的使用(重点)
对比两者的查询,显然这种去重的方式更加适用,重复的数据只显示一条

2.where条件子句

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

逻辑运算符

运算符 语法 描述
and ,&& a and b,a && b 逻辑与
or ,|| a or b,a || b 逻辑或
not ,! not a,! b 逻辑非

3.模糊查询

运算符 语法 描述
is null a is null 如果a为null,返回true
is not null a is not null 如果a不为null,返回true
between…and… a between b and c 若a在b、c之间,返回true
Like a like b SQL匹配,如果a匹配b,返回true
in a in (a1,a2,a3,a4…) 如果a在 (a1,a2,a3…) 中的某一个,则返回true

模糊查询举例:

  • like相关操作(能够进行模糊匹配)
#查询名字是刘开头的(姓刘的)
select * from `student` where `studentname` like "刘%"	--%(代表0到任意个字符)
#查询姓刘的同学,姓名只有两个字的
select * from `student` where `studentname` like "刘_"	--_(代表一个字符)
#查询姓刘的同学,姓名为三个字的
select * from `student` where `studentname` like "刘__"
#查询姓名中带有"家"字的同学
select * from `student` where `studentname` like "%家%"
  • in相关操作(in只能具体匹配)
#查询1001,1002,1003号学生
select * from `student` where `studentno` in (1001,1002,1003)
#查询在安徽、北京的学生
select * from `student` where `address` in ('安徽','北京')
  • null、not null相关操作
#查询地址为空的学生,空可能是""或者null
select * from `student` where `address` = '' or `address` is null
#查询有出生日期的学生,即出生日期不为空
select * from `student` where `borndate` is not null

4.联表查询

我们在做查询的时候,会遇到可能一张表满足不了我们要求的情况,可能要求获取的数据来自于两张、三张甚至更多张表,对此,我们就应该使用联表查询。

举个例子:
根据之前我们新建的数据库和表,我们提一个需求,获取参加了考试的学生的信息,包括学生的姓名,学号,学生考试的科目的编号,分数

select * from `student`
select * from `result`

这样查询出来的效果,我们还需要一个一个对照着学生的学号去找,这种方式过于麻烦,我们需要用一种方式将这些数据拼接起来,方便我们查看。

思路:

  • 分析需求:分析查询的字段来自于那些表
  • 连接方式:确定使用哪种连接方式查询(确定交叉点,即这两个表中哪些数据是相同的)

根据分析两张表结构,我们可以判断的条件为:学生表中的studentNo = 成绩表中的studentNo

#使用inner join联表查询
select s.`studentNo`,`studentName`,`subjectNo`,`studentResult`
from `student` as s inner join `result` as r
where s.`studentNo` = r.`studentNo`
#使用right join联表查询
select s.`studentNo`,`studentName`,`subjectNo`,`studentResult`
from `student` as s right join `result` as r
on s.`studentNo` = r.`studentNo`
#使用left join联表查询
select s.`studentNo`,`studentName`,`subjectNo`,`studentResult`
from `student` as s left join `result` as r
where s.`studentNo` = r.`studentNo`
  • join on 连接查询
  • where 等值查询
操作 描述
inner join 如果表中至少有一个匹配,就返回,如果两张表都有,就确定是哪张表即可
left join 即使右表中没有值与左表匹配,也会返回左表所有的值
right join 即使左表中没有值与右边的值相匹配,也会返回右表所有的值

如果我们需要查两张以上的表,先对前面两张表进行查询,再将查询到的结果与第三张表进行连接。

#查询学生的学号,姓名,科目,成绩(来自三张表)
SELECT stu.studentno,studentname,sub.subjectname,studentresult 
from student stu INNER join result res 
on stu.studentno = res.studentno
right join subject sub 
on stu.studentno = res.studentno

5.七种join理论:

9.高级的Select语句的使用(重点)

6.自连接查询

自连接:顾名思义就是自己和自己连接,核心就是将一张表拆为两张一样的表即可。

我们在现有的school数据库中新建一个表category

drop table if exists `category`
CREATE TABLE if not exists `category`( 
	`categoryid` INT(3) NOT NULL COMMENT'id', 
	`pid` INT(3) NOT NULL COMMENT'父id 没有父则为1', 
	`categoryname` VARCHAR(10) NOT NULL COMMENT'种类名字', 
	PRIMARY KEY (`categoryid`) 
) ENGINE=INNODB CHARSET=utf8; 

INSERT INTO `category` (`categoryid`, `pid`, `categoryname`) VALUES (2, 1, "信息技术"), (3, 1, "软件开发"),(5, 1, "美术设计"), (4, 3, "数据库"),(8, 2, "办公信息"), (6, 3, "web开发"), (7, 5, "ps技术");

9.高级的Select语句的使用(重点)
我们分析这张表,可以看出,在这张表内实现了分级,例如web开发,它的id为6,但是它的父id为3,而id为3的软件开发父id又为1。我们拆分一下这张表。

  • 父表
categoryid categoryname pid
2 信息技术 1
3 软件开发 1
5 美术设计 1
  • 子表
categoryid categoryname pid
4 数据库 3
8 办公信息 2
6 web开发 3
7 美术设计 5

操作:查询父类对应的子类关系

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

我们要进行查询,这应该是我们想要的查询结果。

对于都在一个表中的字段,我们就使用自连接查询。

select a.categoryname 科目类别,b.categoryname 课程
from category a inner join category b
on a.categoryid = b.pid 

9.高级的Select语句的使用(重点)

7.分页和排序查询

(1)排序查询

  • 升序(asc):

查询结果根据成绩来升序排序

select * from `result` ORDER BY `studentresult` asc

9.高级的Select语句的使用(重点)

  • 降序(desc):
select * from `result` ORDER BY `studentresult` desc

9.高级的Select语句的使用(重点)

  • order by:通过那个字段排序
  • desc、asc:desc降序,asc升序

(2)分页查询

思考一下:为什么要用分页查询?
我们在一个很庞大的数据库中去寻找数据,如果要全部展示,数据库的压力会非常大,而且我们查找数据也极不方便,因此,我们需要用到分页。

  • 使用limit进行分页查询
SELECT * from subject limit 0,10

9.高级的Select语句的使用(重点)

  • limit a, b:从索引为 a 开始显示 b 条数据

练习题:

查询科目大于60分的所有学生,显示前10条,并降序排列,字段只显示学生名称,科目名称,成绩

SELECT studentname 学生姓名,sub.subjectname 科目名称,studentresult 学生成绩
from student stu inner join  result res
on stu.studentno = res.studentno
inner join subject sub
where res.subjectno = sub.subjectno
and studentresult>60 ORDER BY studentresult desc limit 0,10

8.子查询和嵌套查询

之前我们在写sql,查询条件中的值都是固定的,如果将条件中的值换成计算出来的话,就是子查询了。
本质:在where条件下嵌套一个查询语句

示例:

#查询高等数学-1的所有考试结果(包含学号,姓名,科目编号,成绩),按照成绩降序排列

--使用连接查询
select stu.studentno,studentname,res.subjectno,studentresult
from student stu 
inner join result res
on stu.studentno = res.studentno
inner join subject sub
on res.subjectno = sub.subjectno
where subjectname = '高等数学-1'
order by studentresult desc

--使用子查询
select stu.studentno,studentname,res.subjectno,studentresult
from student stu 
inner join result res
on stu.studentno = res.studentno
where res.subjectno = (select subjectno from subject where subjectname = '高等数学-1')
order by studentresult desc

再来一题


#查询科目为高等数学-2且科目分数不小于80分的学生的学号和姓名
#联表查询方式
select distinct stu.studentno,studentname
from student stu
inner join result res
on stu.studentno = res.studentno
inner join subject sub
on res.subjectno = sub.subjectno
where subjectname = '高等数学-2'
and studentresult >= 80
#子查询方式一、
select stu.studentno,studentname
from student stu
inner join result res
on stu.studentno = res.studentno
where subjectno = (
	select subjectno from subject where subjectname='高等数学-2'
)
and studentresult >=80
#子查询方式二、
select studentno,studentname from student where studentno in (
	select studentno from result where subjectno = (
		select subjectno from subject where subjectname = '高等数学-2'
	) and studentresult >= 80
)

#查询科目有“高等数学”关键字的成绩前五名同学的信息(学号,姓名,分数)
select stu.studentno,studentname,studentresult
from student stu inner join result res
where subjectno in (
	select subjectno from subject where subjectname like "高等数学%"
) order by studentresult desc limit 0,5
上一篇:mysql创建索引的原则


下一篇:Exp2-后门原理与实践 20181223何家豪