MySQL(6):多表查询

多表查询,也称为关联查询,指两个或更多个表一起完成查询操作
前提条件: 这些一起查询的表之间是有关系的(一对一、一对多),它们之间一定是有关联字段,这个关联字段可能建立了外键,也可能没有建立外键。 比如:员工表和部门表,这两个表依靠"部门编号"进行关联。

一个案例引发的多表连接

sql 复制代码
DESC employees;
sql 复制代码
DESC departments;
sql 复制代码
DESC locations;

示例(反): 查询员工为 'Abel' 的人在哪儿工作

sql 复制代码
SELECT *
FROM employees
WHERE last_name = 'Abel';

SELECT *
FROM departments
WHERE department_id = 80;

SELECT *
FROM locations
WHERE location_id = 2500;


虽然结果可以,但是,操作复杂,三次操作!

多表查询

sql 复制代码
# 错误的实现方式:每个员工都与每个部门匹配了一遍
SELECT employee_id,department_name
FROM employees,departments; 

笛卡尔积

笛卡尔乘积是一个数学运算。假设我有两个集合 XY,那么 XY 的笛卡尔积就是 XY 的所有可能组合,也就是第一个对象来自于 X,第二个对象来自于 Y 的所有可能。组合的个数即为两个集合中元素个数的乘积数

笛卡尔积的错误会在下面条件下产生:

1.省略多个表的连接条件(或关联条件);

2.连接条件(或关联条件)无效;

3.所有表中的所有行互相连接;

为了避免笛卡尔积, 可以在 WHERE 加入有效的连接条件。

加入连接条件后,查询语法:

sql 复制代码
SELECT table1.column, table2.column
FROM table1, table2
WHERE table1.column1 = table2.column2;  #连接条件

避免笛卡尔积,正确实现方式:

sql 复制代码
#正确的实现方式
SELECT employee_id,department_name
FROM employees,departments
WHERE employees.department_id = departments.department_id;


表中有相同列时,在列名之前加上表名前缀。
多表查询时,尽量每个字段都指明其所在的表。

多表查询分类

等值连接

等值连接指的是,多表查询语句中的连接条件使用的是等号。

多个连接条件与 AND 操作符

区分重复的列名

多个表中有相同列时,必须在列名之前加上表名前缀。

在不同表中具有相同列名的列可以用 表名 加以区分

sql 复制代码
SELECT employees.last_name, departments.department_name,employees.department_id
FROM employees, departments
WHERE employees.department_id = departments.department_id;

表的别名
可以给表起别名,在SELECTWHERE中使用表的别名。

sql 复制代码
SELECT last_name, department_name
FROM employees, departments
WHERE employees.department_id = departments.department_id;
# 等价
SELECT last_name, department_name
FROM employees emp, departments dep
WHERE emp.department_id = dep.department_id;

【 强制 】对于数据库中表记录的查询和变更,只要涉及多个表,都需要在列名前加表的别名(或表名)进行限定。

说明:对多表进行查询记录、更新记录、删除记录时,如果对操作列没有限定表的别名(或表 名),并且操作列在多个表中存在时,就会抛异常。

正例:select t1.name from table_first as t1 , table_second as t2 where t1.id=t2.id;

反例:在某业务中,由于多表关联查询语句没有加表的别名(或表名)的限制,正常运行两年后,最近在某个表中增加一个同名字段,在预发布环境做数据库变更后,线上查询语句出现出 1052 异常:Column 'name' in field list is ambiguous。

连接多个表

连接 n个表,至少需要n-1个连接条件。比如,连接三个表,至少需要两个连接条件。

sql 复制代码
# 查询员工的 employee_id,last_name,department_name,city
SELECT employee_id,last_name,department_name,city
FROM employees e,departments d,locations l
WHERE e.`department_id` = d.`department_id` 
AND d.`location_id` = l.`location_id`;

非等值连接

多表查询语句中的连接条件不是使用等号的称为非等值连接。

sql 复制代码
SELECT e.last_name, e.salary, j.grade_level
FROM employees e,job_grades j
#where e.`salary` between j.`lowest_sal` AND j.`highest_sal`
WHERE e.`salary` >= j.`lowest_sal` AND e.`salary` <= j.`highest_sal`;

自连接 vs 非自连接

内连接和外连接

内连接: 合并具有同一列的两个以上的表的行, 结果集中不包含一个表与另一个表不匹配的行
外连接: 两个表在连接过程中除了返回满足连接条件的行以外还返回左(或右)表中不满足条件的行 ,这种连接称为左(或右) 外连接没有匹配的行时, 结果表中相应的列为空(NULL)

如果是左外连接,则连接条件中左边的表也称为 主表 ,右边的表称为 从表

如果是右外连接,则连接条件中右边的表也称为 主表 ,左边的表称为 从表

数据库学习视频:
【MySQL数据库入门到大牛,mysql安装到优化,百科全书级,全网天花板】

相关推荐
闪电悠米20 分钟前
黑马点评-Redis ZSet-实现关注 Feed 流
服务器·网络·数据库·redis·缓存·junit·lua
天疆说22 分钟前
在 Ubuntu 24.04 上安装 MATLAB R2021b
数据库·ubuntu·matlab
码云数智-大飞23 分钟前
Go Channel 详解:并发通信的正确姿势
前端·数据库·git
Volunteer Technology38 分钟前
Flink Table API与SQL(二)
大数据·数据库·flink
杨云龙UP42 分钟前
Spotlight 接入 Oracle 数据库监控操作指南 2026-06-16
数据库·oracle·性能监控·预警·阈值·spotlight·瓶颈分析
正在走向自律43 分钟前
KingbaseES MySQL模式深度解析,从语法兼容到迁移的全栈指南
数据库·数据库架构·kingbasees·电科金仓
叫我:松哥1 小时前
基于Python flask的中学可控智能命题系统设计与实现,整合遗传算法、DeepSeek 大模型及数据库技术构建一体化应用
数据库·人工智能·python·算法·机器学习·flask·遗传算法
阿维的博客日记1 小时前
Hippo4j 线程池监控接入方法
数据库·hippo4j
审判长烧鸡1 小时前
数据库字段命名规范速查表
数据库·sql
承渊政道1 小时前
【MySQL数据库学习】(MySQL表的内外连接)
数据库·学习·mysql·leetcode·bash·数据库开发·数据库系统