MYSQL select 语法(三): JOIN 连接查询
JOIN 从句可以在 SELECT 查询,多表删除,以及更新 语句中使用。但更多的是在查询中使用。
table_references:
escaped_table_reference [, escaped_table_reference] ...
escaped_table_reference: {
table_reference
| { OJ table_reference }
}
table_reference: {
table_factor
| joined_table
}
table_factor: {
tbl_name [PARTITION (partition_names)]
[[AS] alias] [index_hint_list]
| [LATERAL] table_subquery [AS] alias [(col_list)]
| ( table_references )
}
joined_table: {
table_reference {[INNER | CROSS] JOIN | STRAIGHT_JOIN} table_factor [join_specification]
| table_reference {LEFT|RIGHT} [OUTER] JOIN table_reference join_specification
| table_reference NATURAL [INNER | {LEFT|RIGHT} [OUTER]] JOIN table_factor
}
join_specification: {
ON search_condition
| USING (join_column_list)
}
join_column_list:
column_name [, column_name] ...
index_hint_list:
index_hint [, index_hint] ...
index_hint: {
USE {INDEX|KEY}
[FOR {JOIN|ORDER BY|GROUP BY}] ([index_list])
| {IGNORE|FORCE} {INDEX|KEY}
[FOR {JOIN|ORDER BY|GROUP BY}] (index_list)
}
index_list:
index_name [, index_name] ...
- 1、连接语句分为: 内连接(inner join) 和 外连接(outer join)。其中外连接又分为:左外连接(left outer join),右外连接(right outer join)。
JOIN 连接语句的作用简单的讲是: 通过某些方式将多个表横向拼接在一块,各个列组成新的行。与之相对的是 UNION 联合语句是:将多个表的行竖向拼接在一起,数据行的堆叠。
如:
T1 T2
---- ----
a b a c
1 x 2 z
2 y 3 w
>SELECT * FROM T1 INNER JOIN T2;
a b a c
1 x 2 z
1 x 3 w
2 y 2 z
a y 3 w
>SELECT * FROM T1 LEFT JOIN T2 ON T1.a = T2.a;
a b a c
1 x NULL NULL
2 y 2 z
- 2、JOIN 连接的原理是使用 嵌套循环算法 :多个表形成多重循环,根据ON 后面的条件,每一行拼接起来。
以上面的例子为例:
1)内连接:T1表为外循环,T2表是内循环,最后形成笛卡尔积表。最后的总行数是 每个表行数的乘积。
执行的过程是:T1表的第一行,和 T2 表的每一行都拼接形成新的一行;T1表的第二行,和 T2 表的每一行都拼接形成新的一行;.... 直至T1表的最后一行和 T2 表的每一行拼接结束。
foreach row t1 in T1 {
foreach row t2 in T2 {
t:= t1 || t2
}
}
output t
2)左连接:T1表为外循环,T2表是内循环
执行的过程是 : 将T1表的第一行 循环比较 T2 的每一行,如果满足 连接条件,就拼接形成新的一行,如果T2表没有一行满足条件,则仍然会添加新的一行,这行数据包含 t1,t2的所有列, t1 的值不变,t2 的所有列的值为NULL;
将T1表的第二行 循环比较 T2 的每一行,如果满足 连接条件,就拼接形成新的一行;
...
以此类推,直至 T1表的最后一行行 循环比较 T2 的每一行。
foreach row t1 in T1 {
t_tmp = NULL
foreach row t2 in T2 {
if t1.a = t2.a
t_tmp := t1 || t2
}
if t_tmp = NULL
t := t1 || NULL
}
output t
-
3、在 MySQL 中关键字 JOIN, CROSS JOIN, 和 INNER JOIN 在语法上是等同的,都表示 内连接。
INNER JOIN 和 逗号(,)连接,在 没有 连接条件时是 一样的,都会产生笛卡尔积。但 逗号 连接的优先级比其他连接都低。
如果存在连接条件时,混用 逗号连接 和 其他连接 会 出错。 -
4、search_condition ON 后面的条件,可以是任何用在 where 条件中的表达式。但连接条件是指定怎么连接表,而 WHERE 从句是限制那些行可以导出到结果集。
-
5、在 LEFT JOIN 中,如果 ON 或 USING 右边的表 没有匹配的行,则将这表的一行所有列都设置为 NULL
-
6、USING(join_column_list) 指定特殊的连接条件,等同于 ON 从句。其中包含的列必须是所有表都有的列
a LEFT JOIN b USING (c1, c2, c3)
- 7、右连接工作模式和 左连接 相似。建议使用 左连接。
https://dev.mysql.com/doc/refman/8.0/en/select.html
https://dev.mysql.com/doc/refman/8.0/en/join.html
https://dev.mysql.com/doc/refman/8.0/en/nested-loop-joins.html =》 Nested-Loop Join Algorithms
https://dev.mysql.com/doc/refman/8.0/en/nested-join-optimization.html
https://dev.mysql.com/doc/refman/8.0/en/outer-join-optimization.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!