MySQL的表连接及案例演示

MySQL的表连接及案例演示

  • MySQL的表连接
    • [内连接 inner join](#内连接 inner join)
    • 外连接
      • [左外连接 left join](#左外连接 left join)
      • [右外连接 right join](#右外连接 right join)
    • 自连接
    • [交叉连接 cross join](#交叉连接 cross join)
    • [合并 union & union all](#合并 union & union all)
    • 案例演示

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. 合并不去重

相关推荐
光羽隹衡6 小时前
SQL的导入导出数据和查询
数据库·sql
爱技术的阿呆6 小时前
MySQL子查询及其案例
数据库·mysql
..空空的人6 小时前
C++基于protobuf实现仿RabbitMQ消息队列---技术认识2
服务器·数据库·c++·网络协议·gtest·异步·protobuf
小妖同学学AI6 小时前
告别SQL编写!开源WrenAI实现自然语言与数据库的智能对话
数据库·sql·开源
DBA小马哥7 小时前
PB级数据迁移挑战:Oracle故障响应优化实战
数据库·oracle
Logic1017 小时前
《Mysql数据库应用》 第2版 郭文明 实验1 在MySQL中创建数据库和表核心操作与思路解析
数据库·sql·mysql·学习笔记·计算机网络技术·形考作业·国家开放大学
Haooog7 小时前
Redis面试题(不定时更新)
数据库·redis·缓存·面试
孙同学_7 小时前
【Linux篇】线程互斥、同步与线程池设计:原理与实践
数据库·redis·缓存
running up7 小时前
JDBC-一套操作数据库的api
数据库