1. 程式人生 > 其它 >MYSQL select 語法(三): JOIN 連線查詢

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