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

举例:

相关推荐
一个响当当的名号2 小时前
lecture18 多版本并发控制
数据库·oracle
Volunteer Technology2 小时前
Oracle高级部分(子程序)
数据库·oracle
..过云雨2 小时前
【MySQL】1. MySQL安装
数据库·mysql
Shea3012 小时前
如何优化深度分页的性能问题
mysql
紫微AI2 小时前
文件系统就是新的数据库:我是如何为 AI Agent 构建个人操作系统的
数据库·人工智能
小红卒2 小时前
Redis数据库四种getshell方法研究
数据库·redis·网络安全
Coder_Boy_3 小时前
技术交流总结:分布式、数据库、Spring及SpringBoot核心知识点梳理
数据库·spring boot·分布式·spring·微服务
专注VB编程开发20年3 小时前
单服务器的 IIS + ASP.NET页面来说不需要redis
数据库·redis·缓存
知识分享小能手3 小时前
SQL Server 2019入门学习教程,从入门到精通,SQL Server 2019 新增功能 — 语法知识点及使用方法详解(20)
数据库·学习·sqlserver