【MySQL | 第四篇】多表查询

目录

一、多表关系

1.一对N

2.N对N

3.一对一

二、什么是多表查询?

1.概述

2.分类------连接查询

①连接查询------内连接

②连接查询------外连接

③连接查询------自连接

3.分类------联合查询

4.分类------子查询

①标量子查询

②列子查询

③行子查询

④表子查询


一、多表关系

多表关系由三类组成,分别为一对N、N对N、一对一。

1.一对N

案例:部门和员工之间的关系。

关系:一个部门对应多个员工,一个员工对应一个部门。

实现:在多的一方建立外键,指向一的一方的主键。

2.N对N

案例:学生与课程的关系。

关系:一个学生可以选择多门课程,一门课程可以由多个学生选择。

实现:建立一个第三方表,第三方表包含两个外键,分别关联两方的主键。

3.一对一

案例:用户与用户详情的关系。

关系:一对一关系,多用于单表拆分,将一张表的基础字段放在一张表中,其他详情字段放到另一张表中。

实现:在任意一方加入外键,关联另外一方的主键, 并设置外键为唯一(UNIQUE)。

二、什么是多表查询?

1.概述

多表查询:顾名思义,指从多张表中查询数据。

笛卡尔积:笛卡尔乘积是指在数学中,两个集合A和集合B的所有组合情况,在多表查询时,需要消除无效的笛卡尔积。

2.分类------连接查询

  • 连接查询
    • 内连接:查询A、B交集部分的数据。
    • 外连接:
      • 左外连接:查询左表所有数据,以及两张表交集部分数据。
      • 右外连接:查询右表所有数据,以及两张表交集部分数据。
    • 自连接:当前表与自身的连接查询,自连接必须使用表别名。
  • 子查询

①连接查询------内连接

查询A、B交集部分的数据。

内连接查询语法:

  • 隐式内连接
sql 复制代码
SELECT 字段列表 FROM 表1, 表2 WHERE 条件......;
  • 显式内连接
sql 复制代码
SELECT 字段列表 FROM 表1 [INNER] JOIN 表2 ON 连接条件......;

案例:

复制代码
查询每个员工的姓名,及关联的部门的名称(隐式内连接)
sql 复制代码
select emp.name,dept.name
from emp, dept
where emp.dept_id=dept.id;
复制代码
查询每个员工的姓名,及关联的部门的名称(显式内连接)
sql 复制代码
select e.name, d.name
from emp e inner join dept d
on e.dept_id = d.id;

②连接查询------外连接

外连接查询语法:

  • 左外连接
sql 复制代码
SELECT 字段列表 FROM 表1 LEFT [OUTER] JOIN 表2 ON 条件...;
  • 右外连接
sql 复制代码
SELECT 字段列表 FROM 表1 RIGHT [OUTER] JOIN 表2 ON 条件...;

案例:

复制代码
查询emp的所有数据,和对应的部门名称
sql 复制代码
select e.*, d.name
from emp e left outer join dept d
on e.dept_id = d.id;

运行结果:

③连接查询------自连接

自连接查询语法:

sql 复制代码
SELECT 字段列表 FROM 表A 别名A JOIN 表A 别名B ON 条件...;

自连接查询,可以是内连接查询,也可以是外连接查询。

案例

复制代码
查询员工及其所属领导的名字
sql 复制代码
select a.name, b.name
from emp a join emp b
on a.managerid = b.id;

运行结果:

复制代码
查询员工及其所属领导的名字,如果员工没有领导,也需要查询出来
sql 复制代码
select a.name '员工', b.name '领导'
from emp a left join emp b
on a.managerid = b.id;

运行结果:

3.分类------联合查询

联合查询-union,union all。

对于union查询,就是把多次查询的结果合并起来,形成一个新的查询结果集。

sql 复制代码
SELECT 字段列表 FROM 表A ......
UNION [ALL]
SELECT 字段列表 FROM 表B ......;

案例:

复制代码
将薪资低于5000的员工,和年龄大于50的员工全部查询出来。
sql 复制代码
select * from emp where salary < 5000
union all
select * from emp where age > 50;

如果要去重,则使用union:

sql 复制代码
select * from emp where salary < 5000
union
select * from emp where age > 50;

注:在使用联合查询时,使用union连接的两条语句的返回的列数必须一致。

4.分类------子查询

概念:SQL语句中嵌套SELECT语句,称为嵌套查询,又称子查询。

sql 复制代码
SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);

根据子查询结果不同,分为:

  • 标量子查询(子查询结果为单个值)
  • 列子查询(子查询结果为一列)
  • 行子查询(子查询结果为一行)
  • 表子查询(子查询结果为多行多列)

根据子查询位置,分为:WHERE之后、FROM之后、SELECT之后。

①标量子查询

案例:查询销售部的员工信息。

sql 复制代码
select * from emp where dept_id = (select id from dept where name = '销售部');

②列子查询

子查询结果为一列(可以是多行),这种子查询称为列子查询。

常用的操作符:IN,NOT IN, ANY, SOME,ALL

案例:查询销售部和市场部的所有员工信息

sql 复制代码
select * from dept where dept_id in (select id from dept where name = '销售部' or name = '市场部');

③行子查询

子查询返回的结果为一行(可以是多列),这种子查询称为行子查询。

常用的操作符:= <> IN NOT IN

案例:查询与张无忌的薪资与直属领导相同的员工信息

sql 复制代码
select * from emp where (salary, managerid) = ( select salary, managerid from emp where name = '张无忌' );

④表子查询

子查询返回的结果为多行多列,这种子查询称为表子查询。

常用操作符:IN

案例:查询入职日期是"2006-01-01"之后的员工信息,及其部门信息

sql 复制代码
select e.*, d.* from (select * from emp where entrydate > '2006-01-01') e
left join dept d
on e.dept_id = d.id;
相关推荐
ao-weilai23 分钟前
MySQL数据库:表约束
数据库·mysql·adb
ly768940 分钟前
Redis 分布式锁的边界条件:Redlock 争议、锁续期与客户端崩溃后的互斥失效
数据库·redis·分布式·分布式锁·watchdog·redlock
kaixin_learn_qt_ing44 分钟前
qgeoview-samples-basic
数据库
Omics Pro1 小时前
微软:多模态生物世界模型
数据库·人工智能·算法·microsoft·机器学习·自然语言处理
字节渡客2 小时前
接口明明返回成功,数据库偶尔就是没写入
数据库
Ivanqhz2 小时前
KV Cache
服务器·数据库·人工智能·深度学习·算法
Omics Pro2 小时前
~30,000+引用!理论2005,R包2008,多组学集成AI增强
开发语言·数据库·人工智能·算法·机器学习·自然语言处理·r语言
呆萌很2 小时前
数据库逻辑结构设计
数据库
howdoyoudo2026062 小时前
当新案例冲击旧框架:分类系统的宿命与修正路径
大数据·网络·数据库·人工智能·安全·ai·分类
自己的九又四分之三站台2 小时前
GeoPackage 到底适合什么场景:从 SQLite 容器到空间数据格式选型
数据库·oracle·sqlite