24人参与 • 2025-02-20 • MsSqlserver
以下是用图表结合代码解释 sql 中多表查询的常见连接方式:
1. 内连接 (inner join) +-------------+ +-------------+ | table a | | table b | +-------------+ +-------------+ | 交集部分 | +-----------+ 2. 左连接 (left join) +-------------+ +-------------+ | table a | | table b | +-------------+ +-------------+ | 全部保留 | | 右表匹配 | 3. 右连接 (right join) +-------------+ +-------------+ | table a | | table b | +-------------+ +-------------+ | 左表匹配 | | 全部保留 | 4. 全外连接 (full outer join) +-------------+ +-------------+ | table a | | table b | +-------------+ +-------------+ | 全部保留 | | 全部保留 |
-- 创建示例表 create table employees ( id int primary key, name varchar(50), dept_id int ); create table departments ( id int primary key, dept_name varchar(50) ); -- 插入测试数据 insert into employees values (1, 'alice', 101), (2, 'bob', 102), (3, 'charlie', 103), (4, 'david', null); insert into departments values (101, 'hr'), (102, 'engineering'), (104, 'marketing');
select e.name as 员工姓名, -- 从 employees 表中选择员工姓名 d.dept_name as 部门名称 -- 从 departments 表中选择部门名称 from employees e -- 主表:employees(别名为 e) inner join departments d -- 连接表:departments(别名为 d) on e.dept_id = d.id; -- 连接条件:员工的部门id = 部门的id
分步图解
假设表中数据如下(基于你之前创建的测试数据):
表 employees
id | name | dept_id |
---|---|---|
1 | alice | 101 |
2 | bob | 102 |
3 | charlie | 103 |
4 | david | null |
表 departments
id | dept_name |
---|---|
101 | hr |
102 | engineering |
104 | marketing |
连接过程
employees(e) departments(d) +----+---------+---------+ +-----+-------------+ | id | name | dept_id | | id | dept_name | +----+---------+---------+ +-----+-------------+ | 1 | alice | 101 | | 101 | hr | | 2 | bob | 102 | | 102 | engineering | | 3 | charlie | 103 | | 104 | marketing | | 4 | david | null | +-----+-------------+ +----+---------+---------+ 通过 inner join 连接条件 e.dept_id = d.id:
关键概念解释
1. inner join
的作用
dept_id
在 departments
表中找不到对应的 id
,该员工会被排除employees
表中无人归属,该部门也会被排除2. 为什么用 e.dept_id = d.id
?
dept_id
)必须等于部门的主键(id
)3. 别名(e
和 d
)的作用
employees e
= 给表起别名 e
)e.name
表示来自员工表,d.dept_name
表示来自部门表)结果输出
员工姓名 | 部门名称 |
---|---|
alice | hr |
bob | engineering |
结果说明
dept_id=103
在 departments
表中不存在dept_id=null
无法匹配任何部门dept_id=104
select e.name, d.dept_name from employees e left join departments d on e.dept_id = d.id;
结果: 包含所有左表记录 + 右表匹配结果(david 的部门为 null)
select e.name, d.dept_name from employees e right join departments d on e.dept_id = d.id;
结果: 包含所有右表记录 + 左表匹配结果(marketing 部门无员工)
-- mysql 不支持 full outer join,需用 union 模拟 select e.name, d.dept_name from employees e left join departments d on e.dept_id = d.id union select e.name, d.dept_name from employees e right join departments d on e.dept_id = d.id;
结果: 包含所有记录(含 null 匹配)
select e.name, d.dept_name from employees e cross join departments d;
结果: 笛卡尔积(4 员工 × 3 部门 = 12 条记录)
连接类型 | 结果记录数 | 包含 null 情况 |
---|---|---|
inner join | 2 | 无 |
left join | 4 | 右表可能为 null |
right join | 3 | 左表可能为 null |
full outer join | 5 | 两侧均可能为 null |
cross join | 12 | 无关联条件,纯组合 |
coalesce()
或 ifnull()
函数的使用可以通过实际运行这些 sql 语句观察不同连接方式的差异。
自连接 (self join) +-------------+ +-------------+ | table | | table | | (别名为a) | | (别名为b) | +-------------+ +-------------+ | 关联自身的字段 | +----------------+
典型场景:员工表查询上下级关系、分类层级关系等
-- 创建带 manager_id 的员工表 create table employees ( id int primary key, name varchar(50), manager_id int ); -- 插入测试数据 insert into employees values (1, 'alice', null), -- 顶级管理者 (2, 'bob', 1), -- 向 alice 汇报 (3, 'charlie', 1), -- 向 alice 汇报 (4, 'david', 2); -- 向 bob 汇报
1. 查询员工及其上级(左连接版)
select e.name as employee, m.name as manager from employees e left join employees m on e.manager_id = m.id;
结果:
+----------+----------+
| employee | manager |
+----------+----------+
| alice | null | -- 没有上级
| bob | alice |
| charlie | alice |
| david | bob |
+----------+----------+
2. 仅查询有上级的员工(内连接版)
select e.name as employee, m.name as manager from employees e inner join employees m on e.manager_id = m.id;
结果:
+----------+---------+
| employee | manager |
+----------+---------+
| bob | alice |
| charlie | alice |
| david | bob |
+----------+---------+
连接方式 | 结果记录数 | 包含 null 情况 | 典型用途 |
---|---|---|---|
自连接-左连接 | 4 | 顶级管理者的上级为 null | 显示完整层级结构 |
自连接-内连接 | 3 | 无 null | 仅显示有上下级关系的记录 |
e
为员工,m
为上级)4.null 处理:
select e.name, coalesce(m.name, '顶级管理者') as manager from employees e left join employees m on e.manager_id = m.id;
到此这篇关于sql 中多表查询的常见连接方式详解的文章就介绍到这了,更多相关sql多表查询连接方式内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论