将数据存在一张表中时,往往会显得很冗余,所以一般在设计表时,很有可能要将 一张表拆分成2张甚至多张的表。在查询时,需要将2张表中的数据按照指定字段(或者某种模 式)联合起来,然后显示其相应的结果。 拆分成多张表之后,肯定有一个字段,让两张或多张表之间可以建立一定的对应关系,避免了数据的冗余。
一、交叉连接
笛卡尔积:两个在进行交叉连接查询时,会进行两两组合,从而产生大量的数据,导致查询效率大大降低。笛卡尔乘积(会导致性能下降:最耗资源,效率极其低)。
格式:select * from 表1,表2 where 表1.字段1 = 表2.字段2
多表查询时,一定要找对表与表之间是通过哪个字段进行连接的
二、内连接
两个表中具有相同意义的字段(有关联意义的字段)进行连接。左右表符合条件的行直接构建成新行,不相等的排除在外。不会产生笛卡尔积现象,查询效率高,内连接只有当两个表中,符合设定条件时,这些数据才会被查找出来。
两个表关联格式:
select
*
from
表
1
inner join
表
2
on
表
1.
字段
=
表
2.
字段
-- 查找所有学生的成绩
select students.name,students.sex,students.class,scores.score from students
inner join scores
on students.studentNo = scores.studentno
可以给表起别名,在使用内连接时,结合别名,可以提升编写速度
两个以上表关联格式:
select
*
from
表
1
inner join
表
2
on
表
1.
字段
=
表
2.
字段
inner join
表
3
on
表
2.
字段
=
表
3.
字段
多表关联时,一定要注意选对关联关系,两个之间必须有一个字段时能够一一对应
-- 查找王昭君的课程及对应的成绩
select students.name,courses.name,scores.score from students
inner join scores
on students.studentNo = scores.studentno
inner join courses
on scores.courseNo=courses.courseNo
三、左连接
以左表为基准,展示左表的全部数据,右表只输出符合条件的数据,右表不存在的数据则使用null表示。left join
左边的表就是左表(即表
1
),
left join
右边的表就是右表(即表
2
)
两表连接格式:
select *
from 表1 left join
表
2
on 表1.
字段
=
表
2.
字段
-- 查找所有学生的成绩,包括没有成绩的学生
select students.name,students.sex,students.class,scores.score from students
left join scores
on scores.studentno = students.studentNo
多表连接:
select * from students as stu
inner join scores as sc
on stu.studentNo = sc.studentno
left join courses co
on sc.courseNo=co.courseNo
where stu.name='王昭君'
备注:首先,先将students和
scores
进行连接查询,这时候产生了一张大表。其次,在使用这张大表和courses
连接,为了保证显示没有课程的学生和成绩,也就是要显示大表中所有数据,这时候,就可以使用左连接。
四、右连接
以右表为基准,展示右表的全部数据,左表只输出符合条件的数据,左表不存在的数据则使用
null表示。right join
左边的表就是左表(即表
1
),
right join
右边的表就是右表(即表
2
)
两表连接格式:
select * from 表1
right join 表2 on
表
1.
字段
=
表
2.
字段
-- 查找所有学生的成绩,包括没有成绩的学生
select students.name,students.sex,students.class,scores.score
from scores right join students
on scores.studentno = students.studentNo
五、联合查询
将两条语句的查询结果联合在一起,放在同一个结果集中显示,就叫联合查询。
关键字 union。两条语句要查询的字段数量必须一致。
查询结果以第一条sql的字段名,作为查询结果的列名。
六、子查询
子查询是将一个查询语句嵌套在另一个查询语句中。内层查询语句的查询结果,可以作为外层查询语句提供条件。
主查询与子查询的关系:
--子查询是嵌入到主查询中
--子查询是辅助主查询的,要么充当条件
,
要么充当数据源
--子查询是可以独立存在的语句,是一条完整的
select
语句
--先执行子查询,再执行父级查询
举例:①查询大于平均年龄的学生有哪些
②查询王昭君学了哪些课程
--1查找王昭君的学号
select studentno from students where name = '王昭君'
--2.根据学号找出对应的课程号
select courseno from scores where studentno = (select studentno from
students where name = '王昭君')
--3.根据课程号找出课程名称
select name from courses where courseno in (select courseno from scores where studentno = (select studentno from students where name = '王昭君'))
--4.合并
select name from courses where courseno in (
select courseno from scores where studentno in (
select studentno from students where name = '王昭君'))
七、子查询中的关键字
(1)in 范围
格式:主查询 where 条件 in (列子查询)
-- 找出所有女生选修的课程(子查询)
---1.找出女生有哪些(她们的学号)
select studentno from students where sex = '女'
---2.找出女生对应的课程编号
select courseno from scores where studentno in
('001','005','006','008','010')
---3.在通过课程编号,找出对应的课程名称
select name from courses where courseno in (1,3,5,6,7)
---4.合并
select name from courses where courseno in (
select courseno from scores where studentno in (
select studentno from students where sex = '女')
(2)not in:取出不在范围中的数据
-- 找出王昭君没有学过的课程有哪些
select name from courses where courseno not in (
select courseno from scores where studentno in (
select studentno from students where name = '王昭君'))
注意事项:
子查询的字段要和主查询条件中所使用的字段相匹配。