多表联查的几种方式

有如下两张表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
mysql> select * from teacher;
+------+-----------+
| t_id | t_name    |
+------+-----------+
|    1 | 张雪峰    |
|    2 | 老子      |
|    3 | 墨子      |
|    4 | 谢逊      |
+------+-----------+
-- ----------------------
mysql> select * from course;
+------+-----------------------+------+
| c_id | c_name                | t_id |
+------+-----------------------+------+
|    1 | python全栈工程师      |    1 |
|    2 | Java全栈工程师        |    2 |
|    3 | linux工程师           |    3 |
|    4 | web                   |    2 |
+------+-----------------------+------+

先来介绍两种常用的
多表联查

1
2
3
4
5
6
7
8
9
mysql> select * from  teacher t,course c where  t.t_id = c.t_id;
+------+-----------+------+-----------------------+------+
| t_id | t_name    | c_id | c_name                | t_id |
+------+-----------+------+-----------------------+------+
|    1 | 张雪峰    |    1 | python全栈工程师      |    1 |
|    2 | 老子      |    2 | Java全栈工程师        |    2 |
|    2 | 老子      |    4 | web                   |    2 |
|    3 | 墨子      |    3 | linux工程师           |    3 |
+------+-----------+------+-----------------------+------+

左连接

保留左表全部数据,以右表填充左表,没有以null填充

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
mysql> select * from  teacher t left join course c on t.t_id = c.t_id;
+------+-----------+------+-----------------------+------+
| t_id | t_name    | c_id | c_name                | t_id |
+------+-----------+------+-----------------------+------+
|    1 | 张雪峰    |    1 | python全栈工程师      |    1 |
|    2 | 老子      |    2 | Java全栈工程师        |    2 |
|    3 | 墨子      |    3 | linux工程师           |    3 |
|    2 | 老子      |    4 | web                   |    2 |
|    4 | 谢逊      | NULL | NULL                  | NULL |
+------+-----------+------+-----------------------+------+
 
 
mysql> select * from  teacher t left join course c on t.t_id = c.t_id where c_id = '2';
+------+--------+------+---------------------+------+
| t_id | t_name | c_id | c_name              | t_id |
+------+--------+------+---------------------+------+
|    2 | 老子   |    2 | Java全栈工程师      |    2 |
+------+--------+------+---------------------+------+
 
 
mysql> select * from  teacher t left join course c on t.t_id = c.t_id and c_id = '2';
+------+-----------+------+---------------------+------+
| t_id | t_name    | c_id | c_name              | t_id |
+------+-----------+------+---------------------+------+
|    1 | 张雪峰    | NULL | NULL                | NULL |
|    2 | 老子      |    2 | Java全栈工程师      |    2 |
|    3 | 墨子      | NULL | NULL                | NULL |
|    4 | 谢逊      | NULL | NULL                | NULL |
+------+-----------+------+---------------------+------+

后面来不常用的
右连接 -- 左连接和右连接成为外连接

保留右表全部数据,以左表填充右表,没有以null填充 -- 其实就是把左连接的两个表的位置互换

1
2
3
4
5
6
7
8
9
mysql> select * from  teacher t right join course c on t.t_id = c.t_id;
+------+-----------+------+-----------------------+------+
| t_id | t_name    | c_id | c_name                | t_id |
+------+-----------+------+-----------------------+------+
|    1 | 张雪峰    |    1 | python全栈工程师      |    1 |
|    2 | 老子      |    2 | Java全栈工程师        |    2 |
|    2 | 老子      |    4 | web                   |    2 |
|    3 | 墨子      |    3 | linux工程师           |    3 |
+------+-----------+------+-----------------------+------+

里连接
只连接匹配的行

1
2
3
4
5
6
7
8
9
mysql> select * from  teacher t inner join course c on t.t_id = c.t_id;
+------+-----------+------+-----------------------+------+
| t_id | t_name    | c_id | c_name                | t_id |
+------+-----------+------+-----------------------+------+
|    1 | 张雪峰    |    1 | python全栈工程师      |    1 |
|    2 | 老子      |    2 | Java全栈工程师        |    2 |
|    2 | 老子      |    4 | web                   |    2 |
|    3 | 墨子      |    3 | linux工程师           |    3 |
+------+-----------+------+-----------------------+------+

交叉连接-- 然并卵 ,相当于mysql中不存在的 cross join

产生笛卡尔乘积,两个表的数据交叉匹配--得到的结果没有用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
mysql> select * from  teacher,course;
+------+-----------+------+-----------------------+------+
| t_id | t_name    | c_id | c_name                | t_id |
+------+-----------+------+-----------------------+------+
|    1 | 张雪峰    |    1 | python全栈工程师      |    1 |
|    2 | 老子      |    1 | python全栈工程师      |    1 |
|    3 | 墨子      |    1 | python全栈工程师      |    1 |
|    4 | 谢逊      |    1 | python全栈工程师      |    1 |
|    1 | 张雪峰    |    2 | Java全栈工程师        |    2 |
|    2 | 老子      |    2 | Java全栈工程师        |    2 |
|    3 | 墨子      |    2 | Java全栈工程师        |    2 |
|    4 | 谢逊      |    2 | Java全栈工程师        |    2 |
|    1 | 张雪峰    |    3 | linux工程师           |    3 |
|    2 | 老子      |    3 | linux工程师           |    3 |
|    3 | 墨子      |    3 | linux工程师           |    3 |
|    4 | 谢逊      |    3 | linux工程师           |    3 |
|    1 | 张雪峰    |    4 | web                   |    2 |
|    2 | 老子      |    4 | web                   |    2 |
|    3 | 墨子      |    4 | web                   |    2 |
|    4 | 谢逊      |    4 | web                   |    2 |
+------+-----------+------+-----------------------+------+

全外连接-- full join
full join在mysql中并不存在,他是产生a表和b表的并集,没有匹配的则以null值取代。

在mysql中可以使用union 或union all 来实现(union all 会显示所有的数据,union去掉重复的数据)

1
2
3
4
5
6
7
8
9
10
11
mysql> select * from teacher1;
+------+-----------+
| t_id | t_name    |
+------+-----------+
|    1 | 张雪峰    |
|    2 | 老子      |
|    3 | 墨子      |
|    4 | 谢逊      |
|    5 | 林冲      |
|    6 | 杨枭      |
+------+-----------+

 

union和union all 内部的 SELECT 语句必须拥有相同数量的列,每条 SELECT 语句中的列的顺序必须相同,不然会混乱。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
mysql> select * from ((select * from teacher) union all (select * from  teacher1))s;
+------+-----------+
| t_id | t_name    |
+------+-----------+
|    1 | 张雪峰    |
|    2 | 老子      |
|    3 | 墨子      |
|    4 | 谢逊      |
|    1 | 张雪峰    |
|    2 | 老子      |
|    3 | 墨子      |
|    4 | 谢逊      |
|    5 | 林冲      |
|    6 | 杨枭      |
+------+-----------+
-- union
mysql> select * from ((select * from teacher) union (select * from  teacher1))s;
+------+-----------+
| t_id | t_name    |
+------+-----------+
|    1 | 张雪峰    |
|    2 | 老子      |
|    3 | 墨子      |
|    4 | 谢逊      |
|    5 | 林冲      |
|    6 | 杨枭      |
+------+-----------+

 

posted @   瓜田月夜  阅读(2071)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
点击右上角即可分享
微信分享提示