做服务端接口开发时,经常对数据库进行查询操作,了解并掌握数据库的左连接、右连接、内连接、完全外连接、交叉连接,一对多、多对一、多对多,联合连接等概念和使用就很重要了。
首先给出两个数据表,分别为学生表和课程表,假设一个学生只能选一门课程。
表1:Student
-------------
| ID | Name |
-------------
| 1 | 阿猫 |
| 2 | 阿狗 |
| 3 | 阿猪 |
-------------
表2:Course
-------------
| ID | Cname|
-------------
| 1 | 篮球 |
| 2 | 足球 |
| 4 | 排球 |
-------------
语法:left join 或 left outer join
语句:
select *
from student
left join course on student.ID=course.ID
特点:取两表交集且并保留左表
结果:
--------------------------
| ID | Name | ID | Cname |
--------------------------
| 1 | 阿猫 | 1 | 篮球 |
| 2 | 阿狗 | 2 | 足球 |
| 3 | 阿猪 |NULL| NULL |
--------------------------
语法:right join 或 right outer join
语句:
select *
from student
right join course on student.ID=course.ID
特点:取两表交集且并保留右表
结果:
--------------------------
| ID | Name | ID | Cname |
--------------------------
| 1 | 阿猫 | 1 | 篮球 |
| 2 | 阿狗 | 2 | 足球 |
|NULL| NULL | 4 | 排球 |
--------------------------
语法:full join 或 full outer join
语句:
select *
from student
full join course on student.ID=course.ID
特点:包含左右两表中所有的行
结果:
--------------------------
| ID | Name | ID | Cname |
--------------------------
| 1 | 阿猫 | 1 | 篮球 |
| 2 | 阿狗 | 2 | 足球 |
| 3 | 阿猪 |NULL| NULL |
|NULL| NULL | 4 | 排球 |
--------------------------
语法:join 或 inner join
语句:
select *
from student
inner join course on student.ID=course.ID
特点:显示两张表所有记录一一对应,没有对应上的将会被过滤
结果:
--------------------------
| ID | Name | ID | Cname |
--------------------------
| 1 | 阿猫 | 1 | 篮球 |
| 2 | 阿狗 | 2 | 足球 |
--------------------------
语法:cross join
语句:
select *
from student
cross join course
特点:对两个或者多个表进行笛卡儿积操作
结果:
--------------------------
| ID | Name | ID | Cname |
--------------------------
| 1 | 阿猫 | 1 | 篮球 |
| 2 | 阿狗 | 1 | 篮球 |
| 3 | 阿猪 | 1 | 篮球 |
| 1 | 阿猫 | 2 | 足球 |
| 2 | 阿狗 | 2 | 足球 |
| 3 | 阿猪 | 2 | 足球 |
| 1 | 阿猫 | 4 | 排球 |
| 2 | 阿狗 | 4 | 排球 |
| 3 | 阿猪 | 4 | 排球 |
--------------------------
技巧:如果我们在此时给这条语句加上`where`子句的时候,比如【select * from student cross join course where student.ID = course.ID】,结果和inner join所示执行结果一样
语法:union 或 union all
语句:
select ... from table1
union
select ... from table2
特点:两个或多个的表,相同字段合并起来
疑问:当然上面两表为一对一关系,那么如果表A和表B为一对多、多对一或多对多的时候,我们又该如何写连接SQL语句呢?
解答:其实两表一对多的SQL语句和一对一的SQL语句的写法都差不多,只是查询的结果不一样,当然两表也要略有改动。
---------------------
| student |
---------------------
| Sno | Name | Cno |
---------------------
-------------------
| classes |
-------------------
| Cno | CName |
场景:一个班级可以有多个学生
语句:
select * from classes where Cno = 1;
结果: 查询班级为一班的所有学生
场景:多个学生属于某个班级
语句:
select c.CName
FROM classes as c
JOIN student as s ON s.Cno = c.Cno
WHERE s.Name in ('小明', '小花', '小白', '小红');
结果: 查询这几个学生所在的班级的名称
场景:一个学生可以选择多门课程,一门课程可以被多个学生选择,因此学生表student和课程表course之间是多对多的关系
技巧:当两表为多对多关系的时候,我们需要建立一个中间表student_course,中间表至少要有两表的主键,当然还可以有别的内容
---------------
| student |
---------------
| Sno | Name |
---------------
----------------
| course |
----------------
| Cno | Cname |
----------------
--------------
| SC |
--------------
| Sno | Cno |
--------------
语句:
select
s.Name, c.Cname
from student_course as sc
left join student as s on s.Sno = sc.Sno
left join course as c on c.Cno = sc.Cno
结果: 查询每个学生的姓名,以及所在的班级的名称