我们用一个简单的例子来说明:有一个老师表里面都是班主任,和一个学生表。其中很多学生对应有一个唯一的班主任。很明显,这两张表有明显的关联关系。我们先单独设计两张表,且无关联关系。
students表:
假设我们现在有三个学生,数据如下。这里提一下一个重要的点,所有的数据库必定有id字段且一定是唯一自增。经常有人说有服务器字段是来自服务器,服务器数据id可能重复,所以id不应该设计成唯一且自增,这个说法非常肤浅。id一定是唯一且自增,如果有服务器id应该新加一个如host_id这样的新的字段,而不应该去污染自增id。
teachers表:
同样的。我们新建第二张老师表并插入对应数据:
请注意两张表都有id这个字段,学生表的id=1.2.3是学生们的id。
一般我们可以用students.id来表示学生表的id。
老师表的id=1.2是老师们的id,我们用teachers.id来表示老师表的id。
到目前为止,这两张表没任何关联。我们接下来让两张表产生关联关系。每个学生都有一个班主任的,我们需要为学生表新建一个字段,teacher_id老师的id表明这个学生的老师的id值是多少。
上面的teacher_id值是对应老师表的id值。很明显张三和李四的班主任都是jack,王五的班主任是jim。
问题1: 为什么不把老师信息合并到学生表?分成两个张多麻烦?
(1)我这里信息比较简单只有几个字段,复杂情况下两个表各自可能有几十个字段,其中还有若干是重叠的。这么多字段合并在一起这个表是多么的庞杂。
(2)从逻辑封装的角度来说,不同的数据和信息,分开存储比较符合程序开发规范。
关联查询的使用:
一、过滤筛选:
查询出班主任是jack的所有学生列表,这个比较简单直接在所有的学生中,teacher_id=1的就可以了。可使用navicate自带查询输入sql语句,自带变量提示和大小写自动矫正:
SELECT * FROM students WHERE teacher_id = 1
二、数据联查:
我们现在看到的老师id,但我想在学生列表直接看到老师的名字和年龄。就需要把学生表和老师表两个表的数据联合起来。使用left join关键字联合多表。
A表 left join B表,表示以A表为根基追加B表的字段。
我们需要在学生表的基础上追加teacher_id对应的老师的名字和年龄信息,很明显是学生表left join老师表。
如果你直接left join直接查数据库可能会崩溃,因为直接联查会导致两个数据库两两交叉,数量排列组合式出现。
很明显王五的班主任是jim,严格来说王五和jack这个老师没任何交集。也就是说我们在left join的时候一定要有一个联查条件,从我们这个例子来说,就是学生表数据的teacher_id需要等于老师表数据的id。这样两个表就可以融为一个整体。
SELECT * FROM students
LEFT JOIN teachers
WHERE students.teacher_id = teachers.id
现在,我们已经看到了我们想要的基本样子了,但里面出现了id(1), name(1)这样的奇怪字段,是因为学生表有id和name字段,老师表同样有,字段重复。
此时,我们把取出字段的 * 使用 AS别名 语法如下整理下就可以了:
注意as后的字段有,逗号分割字段: