MYSQL多表联合查询的示例详解
作者:zhangyueping8385
这篇文章主要介绍了MySQL中的多表联合查询,包括交叉连接、内连接、外连接和子查询的分类、语法和示例,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
1. 分类
查询两个及以上的表,主要分类如下:
| 多表查询类型 | 说明与关键字 | 语法示例 |
|---|---|---|
| 交叉连接 | 产生笛卡尔积,一般仅用于了解,不推荐业务使用 | select * from A, B; |
| 内连接 | 只返回两表中匹配到的行,inner 可省略;分为隐式(SQL92)和显式(SQL99)写法 | 隐式:select * from A, B where A.id = B.a_id;显式:select * from A inner join B on A.id = B.a_id; |
| 左外连接 | 左表全部返回,右表只返回匹配行,不匹配显示 NULL;outer 可省略 | select * from A left outer join B on A.id = B.a_id; |
| 右外连接 | 右表全部返回,左表只返回匹配行,不匹配显示 NULL;outer 可省略 | select * from A right outer join B on A.id = B.a_id; |
| 满外连接 | 两表全部返回,不匹配的一侧显示 NULL;MySQL 不原生支持,可用 union 模拟 | select * from A full outer join B on A.id = B.a_id; |
| 子查询 | select 嵌套,在查询中再嵌套查询,用于条件或结果集 | select * from A where id in (select a_id from B); |
| 表自关联 | 将同一张表当成多张表使用,通过别名区分,常用于层级 / 递归场景 | select a.name, b.name from emp a join emp b on a.mgr = b.empno; |
参考图示:

数据准备:
create database if not exists mydb3;
use mydb3;
-- 创建部门表
create table if not exists dept3 (
deptno varchar(20) primary key, -- 部门号
name varchar(20) -- 部门名字
);
-- 创建员工表
create table if not exists emp3 (
eid varchar(20) primary key, -- 员工编号
ename varchar(20), -- 员工名字
age int, -- 员工年龄
dept_id varchar(20) -- 员工所属部门
);
-- 给dept3表添加数据
insert into dept3 values('1001','研发部');
insert into dept3 values('1002','销售部');
insert into dept3 values('1003','财务部');
insert into dept3 values('1004','人事部');
-- 给emp3表添加数据
insert into emp3 values('1','乔峰',20, '1001');
insert into emp3 values('2','段誉',21, '1001');
insert into emp3 values('3','虚竹',23, '1001');
insert into emp3 values('4','阿紫',18, '1001');
insert into emp3 values('5','扫地僧',85, '1002');
insert into emp3 values('6','李秋水',33, '1002');
insert into emp3 values('7','鸠摩智',50, '1002');
insert into emp3 values('8','天山童姥',60, '1003');
insert into emp3 values('9','慕容博',58, '1003');
insert into emp3 values('10','丁春秋',71, '1005');2. 交叉连接查询
返回被连接的两个表的所有数据行的笛卡尔积(理解为一张表的每一行去和另一张表的任意一行进行匹配),例如A表有m行数据,B表有n行数据,则返回 m*n 行数据。笛卡尔积会产生很多冗余数据,需要进行条件筛选。
语法格式:
select * from 表1,表2,表3,...;
举例:
select * from emp3,dept3;
3. 内连接查询
查询多张表的交集。
语法格式:
-- 隐式内连接 select * from A,B where 条件; -- 显式内连接 select * from A inner join B on 条件;
举例:
-- 查询每个部门的所属员工
select * from dept3,emp3 where dept3.deptno = emp3.dept_id;
-- 或
select * from dept3 inner join emp3 on dept3.deptno = emp3.dept_id;
-- 查询研发部门的所属员工
select
dept3.name,emp3.ename
from
dept3
inner join
emp3
on
dept3.deptno = emp3.dept_id
where
dept3.name = '研发部';
-- 查询研发部和销售部的所属员工
select
dept3.name,emp3.ename
from
dept3
inner join
emp3
on
dept3.deptno = emp3.dept_id
where
dept3.name = '研发部' || dept3.name = '销售部';
-- 查询每个部门的员工数,并升序排序
select
dept3.name,count(emp3.ename)
from
dept3
inner join
emp3
on
dept3.deptno = emp3.dept_id
group by
dept3.name
order by
count(ename) asc;
-- 查询人数大于等于3的部门,并按照人数降序排序
select
dept3.name,count(emp3.ename) as total_number
from
dept3
inner join
emp3
on
dept3.deptno = emp3.dept_id
group by
dept3.name
having
total_number > 3
order by
total_number desc;4. 外连接查询
外连接分为左外连接(left outer join)、右外连接(right outer join)、满外连接(full outer join)。
语法格式:
-- 左外连接
select * from 表1
left outer join 表2 on 条件1
left outer join 表3 on 条件2
left outer join 表4 on 条件3;
-- 右外连接
select * from 表1 right outer join 表2 on 条件;
-- 满外连接
select * from 表1 full outer join 表2 on 条件;举例:
--外连接查询 use mydb3; -— 查询哪些部门有员工,哪些部门没有员工 select * from dept3 left outer join emp3 on dept3.deptno = emp3.dept_id; -- 查询哪些员工有对应的部门,哪些没有 select * from dept3 right outer join emp3 on dept3.deptno = emp3.dept_id; -- 使用union关键字实现左外连接和右外连接的并集 -- union 查询结果上下拼接;去重 select * from dept3 left outer join emp3 on dept3.deptno = emp3.dept_id union select * from dept3 right outer join emp3 on dept3.deptno = emp3.dept_id; -- union all 查询结果上下拼接;不去重 select * from dept3 left outer join emp3 on dept3.deptno = emp3.dept_id union all select * from dept3 right outer join emp3 on dept3.deptno = emp3.dept_id;
4. 子查询
就是select的嵌套,特点是:
| 子查询返回数据类型 | 说明 |
|---|---|
| 单行单列 | 返回的是一个具体列的内容,可以理解为一个单值数据 |
| 单行多列 | 返回一行数据中多个列的内容 |
| 多行单列 | 返回多行记录之中同一列的内容,相当于给出了一个操作范围 |
| 多行多列 | 查询返回的结果是一张临时表 |
子查询常用的逻辑关键字如下:
| 关键字 | 核心作用 |
|---|---|
| ALL | 与比较运算符结合,需满足子查询所有返回值的条件 |
| ANY | 与比较运算符结合,满足子查询任意一个返回值的条件即可 |
| SOME | 功能与 ANY 完全等价,是 ANY 的别名,语义上更强调 “存在一些” |
| IN | 判断操作数是否在子查询的返回结果集中,可替代 =ANY |
| EXISTS | 仅判断子查询是否存在返回行,存在则为真,不存在则为假 |
子查询举例:
-- 查询年龄最大的员工信息,显示信息包含员工号、员工名字,员工年龄 SELECT * FROM emp3 WHERE age = (SELECT max(age) FROM emp3); -- 单行单列,输出单个值 -- 查询研发部和销售部的员工信息,包含员工号、员工名字 SELECT -- 内连接 * FROM dept3 INNER JOIN emp3 ON dept3.deptno = emp3.dept_id AND NAME = '研发部' OR NAME = '销售部'; -- 或 SELECT * FROM emp3 WHERE dept_id IN ( SELECT -- 多行单列,输出了多个值 deptno FROM dept3 WHERE (NAME = '研发部' OR NAME = '销售部')); --查询研发部20岁以下的员工信息,包括员工号、员工名字,部门名字 -- 方式一:关联查询 SELECT * FROM emp3 INNER JOIN dept3 ON emp3.dept_id = dept3.deptno WHERE age < 20 AND NAME = '研发部'; -- 或 -- 方式二:子查询 SELECT * FROM emp3 WHERE age < 20 AND dept_id IN (SELECT deptno FROM dept3 WHERE NAME = '研发部'); -- 单行多列 / 多行多列
关键字语法格式:
-- all 语法格式
select
...
from
...
where
c > all(查询语句)
-- 等价于
select
...
from
...
where
c > 结果1 and c > 结果2 and c > 结果3all关键字举例:
到此这篇关于MYSQL多表联合查询的文章就介绍到这了,更多相关mysql多表联合查询内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
