MySQL的表连接及案例演示
MySQL的表连接
内连接 inner join
sql
-- 内连接 inner join, 取交集
-- on 匹配的条件, 若不指定条件, 会将所有的内容都匹配一遍
-- select * from 表1 inner join 表2 on 条件;
-- select 表1.字段, 表2.字段 from 表1 inner join 表2 on 表1.字段=表2.字段;
-- 隐式内连接
-- select * from 表1, 表2 where 条件;
-- select 表1.字段, 表2.字段 from 表1, 表2 where 条件;
外连接
左外连接 left join
sql
-- left join: 返回左表的所有行,右表中无法匹配的数据则显示Null.
-- 表的连接顺序是:表1在左,表2在右;返回表1的所有行,表2中无法匹配的数据则显示Null.
-- select * from 表1 left join 表2 on 条件;
-- 表的连接顺序是:表2在左,表1在右;返回表2的所有行,表1中无法匹配的数据则显示Null.
-- select * from 表2 left join 表1 on 条件;
右外连接 right join
sql
-- right join: 返回右表的所有行,左表中无法匹配的数据则显示Null.
-- 表的连接顺序是:表1在左,表2在右;返回表2的所有行,表1中无法匹配的数据则显示Null.
-- select * from 表1 right join 表2 on 条件;
-- 表的连接顺序是:表2在左,表1在右;返回表1的所有行,表2中无法匹配的数据则显示Null.
-- select * from 表2 right join 表1 on 条件;
自连接
当前表自己连接自己,用来匹配的两个字段在同一张表中。
内连接与外连接应用在同一张表上,通过给该张表起两个不同的别名来实现。
sql
-- select * from 表 as 新表名1, 表 as 新表名2 where 条件;
-- select 字段1,字段2 from 表 as 新表名1, 表 as 新表名2 where 新表名1.字段=新表名2.字段;
-- select * from 表 as 新表名1 left join 表 as 新表名2 on 新表名1.字段=新表名2.字段;
交叉连接 cross join
也叫笛卡尔积,会生成字段的所有组合。
sql
-- select 表1.字段, 表2.字段 from 表1 cross join 表2;
合并 union & union all
sql
-- union 合并且去重
-- select * from 表1 union select * from 表2;
-- union all 合并不去重
-- select * from 表1 union all select * from 表2;
案例演示
sql
-- 创建部门表
create table dept(
dept_id int,
dept_name varchar(10)
);
-- 创建员工表
create table employees(
emp_id int,
emp_name varchar(10),
salary decimal(10, 2),
dept_id int
);
-- 给部门表添加数据
insert into dept values
(1, '技术部'),
(2, '市场部'),
(3, '财务部'),
(4, '人力资源部');
insert into dept values
(5, '销售部');
-- 给员工表添加数据
insert into employees values
(101, '张三', 8000, 1),
(101, '李四', 7500, 2),
(101, '王五', 6800, 3),
(101, '赵六', 9000, 4),
(101, '根根', 8000, 1),
(101, '郭郭', 8800, null);
-- 查询部门表的所有数据
select * from dept;
-- 查询员工表的所有数据
select * from employees;

图1. 部门表

图2. 员工表
- 内连接
sql
-- 通过部门id进行匹配
-- 内连接查询员工的部门名称、员工姓名、员工薪资
select dept.dept_name as 部门名称, # 给字段起别名
emp.emp_name as 员工姓名, emp.salary as 员工薪资
from dept
inner join employees as emp # 给表起别名
on dept.dept_id = emp.dept_id;
-- 内连接查询所有字段
select *
from dept
inner join employees as emp # 给表起别名
on dept.dept_id = emp.dept_id;
-- 隐式内连接
select dept.dept_name as 部门名称,
emp.emp_name as 员工姓名, emp.salary as 员工薪资
from dept, employees as emp
where dept.dept_id=emp.dept_id;

图3-1. 内连接查询部分字段的结果

图3-2. 内连接查询所有字段的结果
内连接相当于取交集,部门表中的销售部和员工表的郭郭这两条数据不会查询到。
- 左外连接
sql
-- 左外连接查询所有字段 部门表 left join 员工表
select *
from dept
left join employees as emp
on dept.dept_id=emp.dept_id;

图4-1. 部门表 left join 员工表的结果
表的连接顺序是:部门表在左,员工表在右;返回部门表的所有行,员工表中无法匹配的数据则显示Null。
sql
-- 交换表的顺序:员工表 left join 部门表
select *
from employees as emp
left join dept
on dept.dept_id=emp.dept_id;

图4-2. 员工表 left join 部门表
表的连接顺序是:员工表在左,部门表在右;返回员工表的所有行,部门表中无法匹配的数据则显示Null。
- 右外连接
sql
-- 右外连接查询所有字段 部门表 right join 员工表
select *
from dept
right join employees as emp
on dept.dept_id=emp.dept_id;
-- 交换表的顺序:员工表 right join 部门表
select *
from employees as emp
right join dept
on dept.dept_id=emp.dept_id;

图5-1. 部门表 right join 员工表
表的连接顺序是:部门表在左,员工表在右;返回员工表的所有行,部门表中无法匹配的数据则显示Null。

图5-2. 员工表 right join 部门表
表的连接顺序是:员工表在左,部门表在右;返回部门表的所有行,员工表中无法匹配的数据则显示Null。
- 自连接
sql
create table managers(
emp_id int, # 员工编号
emp_name varchar(10), # 员工姓名
manager_id int # 领导编号
);
insert into managers values
(1, '张三', null),
(2, '李四', 1),
(3, '王五', 1);
-- 查询员工姓名以及对应的上级领导名字
-- 隐式连接
select a.emp_name 员工姓名, b.emp_name 领导名字
from managers as a, managers as b
where a.manager_id=b.emp_id;
-- 显式连接
select a.emp_name 员工姓名, b.emp_name 领导名字
from managers as a
left join managers as b
on a.manager_id=b.emp_id;

图6-1. 隐式自连接

图6-2. 显式自连接
- 交叉连接
sql
create table color(
color_name varchar(10)
);
create table size(
size_name varchar(10)
);
insert into color values('红色'),('蓝色');
insert into size values('M码'),('L码'),('S
码');
-- 交叉连接 cross join 生成字段值的所有组合
select c.color_name, s.size_name
from color as c
cross join size as s;

图7. 交叉连接的结果
- 合并
sql
create table t1(t1_name varchar(10));
create table t2(t2_name varchar(10));
insert into t1 values('张三'),('李四');
insert into t2 values('李四'),('王五');
-- union 合并且去重
select t1_name
from t1
union
select t2_name
from t2;
-- union all 合并不去重
select t1_name
from t1
union all
select t2_name
from t2;

图8-1. 合并且去重

图8-2. 合并不去重