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 条件;

举例:

相关推荐
睡不醒男孩0308232 小时前
第二篇:深入探索开源数据库高可用:构建基于CLup的PostgreSQL生产级高可用与读写分离架构
数据库·postgresql·开源·clup
Micro麦可乐4 小时前
Spring Boot 实战:从零设计一个短链系统(含完整代码与数据库设计)
数据库·spring boot·后端·哈希算法·雪花算法·短链系统
码农阿豪4 小时前
从零到一:Spring Boot快速接入金仓数据库实战
数据库·spring boot·后端
鼎讯信通4 小时前
风电光缆运维提质增效:G-4000A 光缆故障追踪仪破解风场巡检难题
运维·网络·数据库
三十..5 小时前
MySQL 从入门到高可用架构实战精要
运维·数据库·mysql
cfm_29145 小时前
Redis五大基本数据结构底层了解
数据结构·数据库·redis
真实的菜6 小时前
Redis 从入门到精通(十二):典型业务场景实战 —— 排行榜、限流器、秒杀系统、Session 共享
数据库·redis·python
你想考研啊6 小时前
mysql数据库导出导入
数据库·mysql·oracle
十年编程老舅7 小时前
Linux DRM:底层逻辑与实践架构
数据库·mysql
The Sheep 20237 小时前
Vue复习
linux·服务器·数据库