6、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;

参考图示:

数据准备:

sql 复制代码
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 行数据。笛卡尔积会产生很多冗余数据,需要进行条件筛选。

语法格式:

sql 复制代码
select * from 表1,表2,表3,...;

举例:

sql 复制代码
select * from emp3,dept3;

3. 内连接查询

查询多张表的交集。

语法格式:

sql 复制代码
-- 隐式内连接
select * from A,B where 条件;

-- 显式内连接
select * from A inner join B on 条件;

举例:

sql 复制代码
-- 查询每个部门的所属员工
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)。

语法格式:

sql 复制代码
-- 左外连接
select * from 表1 left outer join 表2 on 条件;

-- 右外连接
select * from 表1 right outer join 表2 on 条件;

-- 满外连接
select * from 表1 full outer join 表2 on 条件;

举例:

相关推荐
l1t几秒前
DeepSeek辅助编写的Oracle dmp转SQL脚本和CSV文件工具
数据库·人工智能·sql·oracle
Carino_U22 分钟前
Innodb底层原理与MySQL日志机制
数据库·mysql
bIo7lyA8v1 小时前
如何用SSH访问远程服务器上的内网服务(如:MySQL、Redis、Kafka)?
服务器·mysql·ssh
稻草猫.1 小时前
Spring事务操作全解析
java·数据库·后端·spring
柚子新一1 小时前
CentOS 7 安装 MySQL 8
mysql
momin~1 小时前
MySQL-part2【MySQL表的增删改查】
数据库·mysql
white-persist2 小时前
【vulhub weblogic CVE-2017-10271漏洞复现】vulhub weblogic CVE-2017-10271漏洞复现详细解析
java·运维·服务器·网络·数据库·算法·安全
sR916Mecz2 小时前
MongoDB 详解、应用场景及案例分析(AI)
数据库·mongodb
执笔画流年呀2 小时前
如何用Navicat来创建表
java·mysql
sR916Mecz2 小时前
pache Hop实战:Windows平台MySQL数据迁移的深度排错与性能调优
数据库·windows·mysql