閱讀70 返回首頁    go 阿裏雲 go 技術社區[雲棲]


JOIN ON 和 WHERE 條件

左連接有2個位置可以添加條件,一個是ON + conditional_expr,一個是WHERE + conditional_expr.

兩種方式表達的意思不一樣,返回的數據也就不一樣.

例如:

mysql> select * from test1 left join test2 on test1.a=test2.a and test1.b=1;
+------+------+------+------+
| a    | b    | a    | b    |
+------+------+------+------+
|    1 |    1 |    1 |    1 |
|    1 |    1 |    1 |    2 |
|    2 |    2 | NULL | NULL |
|    3 |    3 | NULL | NULL |
+------+------+------+------+
4 rows in set (0.00 sec)

mysql> select * from test1 left join test2 on test1.a=test2.a where test1.b=1;   
+------+------+------+------+
| a    | b    | a    | b    |
+------+------+------+------+
|    1 |    1 |    1 |    1 |
|    1 |    1 |    1 |    2 |
+------+------+------+------+
2 rows in set (0.00 sec)


Join 語法:

table_references:
    escaped_table_reference [, escaped_table_reference] ...

escaped_table_reference:
    table_reference
  | { OJ table_reference }

table_reference:
    table_factor
  | join_table

table_factor:
    tbl_name [PARTITION (partition_names)]
        [[AS] alias] [index_hint_list]
  | table_subquery [AS] alias
  | ( table_references )

join_table:
    table_reference [INNER | CROSS] JOIN table_factor [join_condition]
  | table_reference STRAIGHT_JOIN table_factor
  | table_reference STRAIGHT_JOIN table_factor ON conditional_expr
  | table_reference {LEFT|RIGHT} [OUTER] JOIN table_reference join_condition
  | table_reference NATURAL [{LEFT|RIGHT} [OUTER]] JOIN table_factor

join_condition:
    ON conditional_expr
  | USING (column_list)

index_hint_list:
    index_hint [, index_hint] ...

index_hint:
    USE {INDEX|KEY}
      [FOR {JOIN|ORDER BY|GROUP BY}] ([index_list])
  | IGNORE {INDEX|KEY}
      [FOR {JOIN|ORDER BY|GROUP BY}] (index_list)
  | FORCE {INDEX|KEY}
      [FOR {JOIN|ORDER BY|GROUP BY}] (index_list)

index_list:
    index_name [, index_name] ...

其中關於conditional_expr
官方的解釋:
The conditional_expr used with ON is any conditional expression of the form that can be used in a WHERE clause. Generally, the ON clause serves for conditions that specify how to join tables, and the WHERE clause restricts which rows to include in the result set.
大意: ON 後麵的conditional_expr  可以使用WHERE一樣語法,但是ON 後麵是2個表連接的條件,WHERE是結果集過濾的條件.


舉個例子:

建立2個測試表:

mysql> create table test1( a int ,b int);
Query OK, 0 rows affected (0.01 sec)

mysql> create table test2( a int ,b int); 
Query OK, 0 rows affected (0.01 sec)

mysql> insert into test1 values (1,1) ;
Query OK, 1 row affected (0.00 sec)

mysql> insert into test1 values (2,2);
Query OK, 1 row affected (0.00 sec)

mysql> insert into test1 values (3,3);
Query OK, 1 row affected (0.00 sec)

mysql> insert into test2 values (1,1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into test2 values (1,2);
Query OK, 1 row affected (0.01 sec)

mysql> select * from test1;
+------+------+
| a    | b    |
+------+------+
|    1 |    1 |
|    2 |    2 |
|    3 |    3 |
+------+------+
3 rows in set (0.00 sec)

mysql> select * from test2;
+------+------+
| a    | b    |
+------+------+
|    1 |    1 |
|    1 |    2 |
+------+------+
2 rows in set (0.00 sec)
左連接會返回主表test1的所有行,然後根據ON 後麵的條件查找test2的記錄,如果沒有匹配記錄則為NULL:


返回主表記錄,並且根據test1.a=test2.a查找test2的記錄,沒有則返回NULL.

mysql> select * from test1 left join test2 on test1.a=test2.a;
+------+------+------+------+
| a    | b    | a    | b    |
+------+------+------+------+
|    1 |    1 |    1 |    1 |
|    1 |    1 |    1 |    2 |
|    2 |    2 | NULL | NULL |
|    3 |    3 | NULL | NULL |
+------+------+------+------+
4 rows in set (0.00 sec)

返回主表記錄,並且根基test1.a=test2.a and test1.b=1 查找test2的記錄,沒有則返回NULL.



mysql> select * from test1 left join test2 on test1.a=test2.a and test1.b=1;
+------+------+------+------+
| a    | b    | a    | b    |
+------+------+------+------+
|    1 |    1 |    1 |    1 |
|    1 |    1 |    1 |    2 |
|    2 |    2 | NULL | NULL |
|    3 |    3 | NULL | NULL |
+------+------+------+------+
4 rows in set (0.00 sec)

返回主表記錄,並且根基test1.a=test2.a and test2.b=1 查找test2的記錄,沒有則返回NULL.


mysql> select * from test1 left join test2 on test1.a=test2.a and test2.b=1; 
+------+------+------+------+
| a    | b    | a    | b    |
+------+------+------+------+
|    1 |    1 |    1 |    1 |
|    2 |    2 | NULL | NULL |
|    3 |    3 | NULL | NULL |
+------+------+------+------+
3 rows in set (0.00 sec)

如果想返回主表a<=2的記錄,這樣是不行的,ON 後麵的條件test1.a<=2 隻是關聯test2獲取記錄的條件.
mysql> select * from test1 left join test2 on test1.a=test2.a and test1.a<=2;             
+------+------+------+------+
| a | b | a | b |
+------+------+------+------+
| 1 | 1 | 1 | 1 |
| 1 | 1 | 1 | 2 |
| 2 | 2 | NULL | NULL |
| 3 | 3 | NULL | NULL |
+------+------+------+------+
4 rows in set (0.00 sec)
需要放到WHERE 後麵,過濾結果集.
mysql> select * from test1 left join test2 on test1.a=test2.a  where test1.a<=2;    
+------+------+------+------+
| a    | b    | a    | b    |
+------+------+------+------+
|    1 |    1 |    1 |    1 |
|    1 |    1 |    1 |    2 |
|    2 |    2 | NULL | NULL |
+------+------+------+------+
3 rows in set (0.00 sec)


最後更新:2017-10-30 16:04:06

  上一篇:go  Enterprise Library深入解析與靈活應用(6):自己動手創建迷你版AOP框架
  下一篇:go  【OA案例】賦能地勘行業升級,構建“大地質”格局