一、连接查询介绍
属于 DQL 查询,用于多张表联合查询数据 。
MySQL 中使用 join 实现多表连接,分为三类:
inner join:内连接left join:左连接right join:右连接
数据准备
sql
-- 创建数据库
create database db_test2;
use db_test2;
-- 班级表
create table classes(
class_id int primary key auto_increment,
class_name varchar(40) not null unique,
class_remark varchar(200)
);
-- 学生表
create table students(
stu_num char(8) primary key,
stu_name varchar(20) not null,
stu_gender char(2) not null,
stu_age int not null,
cid int
);
-- 班级测试数据
insert into classes(class_name,class_remark) values('Java2204','...');
insert into classes(class_name,class_remark) values('Java2205','...');
insert into classes(class_name,class_remark) values('Java2206','...');
insert into classes(class_name,class_remark) values('Python2205','...');
-- 学生测试数据
insert into students(stu_num,stu_name,stu_gender,stu_age,cid) values('20220101','张三','男',20,1);
insert into students(stu_num,stu_name,stu_gender,stu_age,cid) values('20220102','李四','女',20,1);
insert into students(stu_num,stu_name,stu_gender,stu_age,cid) values('20220103','王五','男',20,1);
insert into students(stu_num,stu_name,stu_gender,stu_age,cid) values('20220104','赵柳','女',20,2);
insert into students(stu_num,stu_name,stu_gender,stu_age,cid) values('20220105','孙七','男',20,2);
-- 无班级的学生,cid为null
insert into students(stu_num,stu_name,stu_gender,stu_age) values('20220106','小红','女',20);
insert into students(stu_num,stu_name,stu_gender,stu_age) values('20220107','小明','男',20);
二、内连接 inner join
只返回两张表匹配条件成立的数据,两边没有匹配的记录不会出现在结果中。
笛卡尔积
不写匹配条件时,A表每条记录和B表每条记录全部互相组合,总条数 = A表条数 × B表条数,大部分数据无业务意义,必须加匹配条件过滤。
语法
sql
-- on:连接匹配条件,推荐写法,先匹配再组合数据,效率高
select * from students inner join classes on students.cid = classes.class_id;
-- where:先生成笛卡尔积,再过滤,效率低,不推荐
select * from students inner join classes where students.cid = classes.class_id;
结果说明:小红、小明(无班级),Java2206、Python2205(无学生)不会被查询出来。
三、左连接 left join
以左边表为基准,左表所有记录全部展示 ;右表匹配到就显示对应数据,没有匹配则字段填充
null。
语法
sql
select * from students left join classes on students.cid = classes.class_id;
结果说明:全部学生都会显示;小红、小明班级相关字段全部为
null。
四、右连接 right join
以右边表为基准,右表所有记录全部展示 ;左表匹配到就显示对应数据,没有匹配则字段填充
null。
语法
sql
select * from students right join classes on students.cid = classes.class_id;
结果说明:全部班级都会显示;Java2206、Python2205对应的学生字段全部为
null。
五、数据表别名
多表查询,表名较长时,可以给表设置别名简化书写;
多张表存在同名字段,必须使用 表名.字段名 区分。
sql
-- 给表设置别名 s、c
select s.stu_name, c.class_name
from students s
inner join classes c
on s.cid = c.class_id;
⚠️ 核心要点总结
| 连接类型 | 特点 |
|---|---|
inner join |
只返回两边互相匹配的数据 |
left join |
保留左表全部数据,右表无匹配填null |
right join |
保留右表全部数据,左表无匹配填null |
- 连接匹配条件使用
on,不要用where做连接匹配;where用于连接完成之后再过滤结果。 - 多表字段重名,必须通过
表别名.字段名指定字段来源。 - 笛卡尔积会产生大量无效数据,多表连接一定要写on匹配条件。