需求:查询学生信息,显示所属班级表
连接查询:将多张表(可以大于2张)进行记录的连接(按照某个指定的条件进行数据拼接):最终记录数有可能变化,字段数一定会增加 (至少两张表的合并)
连接查询的意义:在用户查看数据的时候,需要显示的数据来自多张表
连接查询join 使用方式 左表 join 右表
左表:join 左边的表
右表:join 右边的表
连接查询分为4类:内连接 外连接 自然连接 交叉连接
交叉连接(cross join),从一张表中循环取出每一条记录,每条记录都去另外一张表匹配,匹配一定保留(没有条件匹配)而连接本身字段就会增加(保留)。最终形成的结果是笛卡尔积。
基本语法:
左表 cross 右表; === from 左表 右表(多表数据源)
-- 交叉连接
select * from my_student cross join my_class;
内连接:(inner)join,从左表中取出每一条记录,去右表中与所有的记录进行匹配:匹配必须是某个条件在左表中与右表中相同最终才会保留结果,否则不保留。
基本语法:
左表 [inner] join 右表 on 左表.字段 = 右表.字段;on表示连接条件:条件字段就是代表相同的业务含义。(如my_student.c_id 和 my_class_id)
-- 内连接
select * from my_student inner join my_class on my_student.c_id = my_class.id;
select * from my_student inner join my_class on c_id = my_class.id;
-- 不行,因为id 不唯一 都有
select * from my_student inner join my_class on c_id = id;
字段别名以及表别名的使用:在查询数据的时候,不同表有同名字段,这个时候需要加上表名,而表名太长,通常可以使用别名
-- 表别名和字段别名
select s.* ,c.name as c_name ,c.room as c_room from
my_student as s inner join
my_class as c on s.c_id = c.id;
内连接可以没有连接条件,系统会保留所有结果。变成交叉连接。
内连接还可以使用where代替on,但是通常不用on ,on效率更高。on 是相同再匹配,where是匹配了之后再选择相同的。
外连接:outer join ,以某张表为主,取出里面的所有记录,然后每条与另外一张表进行连接:不管能不能匹配上条件,最终都会保留:能匹配正确保留,不能匹配,其它表等到字段都置空NULL
外连接分为左连接和右连接,是以某张表为主:有主表
- left join :左外连接,以左表为主表
- right join :右外连接 ,以右表为主表
基本语法:左表 left/right join 右表 on 左表.字段 = 右表.字段;on必须有
-- 左连接
select s.* ,c.name as c_name ,c.room as c_room from
my_student as s left join -- 左表为主表,最终记录数不少于左表的记录数。
my_class as c on s.c_id = c.id;
自然连接:natural join 自然连接,就是自动匹配连接条件:系统以字段名字作为匹配模式,(同名字段就作为条件,多个同名字段都作为条件)分为自然内连接 自然外连接
基本语法:左表 natural join 右表;
-- 自然内连接
select * from my_student natural join my_class;
-- 自然左外连接
select * from my_student natural left join my_class;
-- 模拟自然连接
select * from my_student left join my_class using(id);
一般不用自然连接,一般可以用内外连接模拟自然连接:使用同名字段
左表 left/right/inner join 右表 using(字段名);– 使用同名字段作为连接条件:自动合并条件。
-- 交叉连接
-- my_student cross join my_class;是数据源
-- 笛卡尔积没有意义,存在的价值,保证连接结果的完整性
select * from my_student cross join my_class;
-- 内连接
select * from my_student inner join my_class on my_student.c_id = my_class.id;
select * from my_student inner join my_class on c_id = my_class.id;
-- 不行,因为id 不唯一 都有
select * from my_student inner join my_class on c_id = id;
-- 表别名和字段别名
select s.* ,c.name as c_name ,c.room as c_room from
my_student as s inner join
my_class as c on s.c_id = c.id;
-- 左连接
select s.* ,c.name as c_name ,c.room as c_room from
my_student as s left join -- 左表为主表,最终记录数不少于左表的记录数。
my_class as c on s.c_id = c.id;
-- 自然内连接
select * from my_student natural join my_class;
-- 自然左外连接
select * from my_student natural left join my_class;
-- 模拟自然连接
select * from my_student left join my_class using(id);