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