JOIN ON 和 WHERE 条件

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 左连接有2个位置可以添加条件,一个是ON + conditional_expr,一个是WHERE + conditional_expr. 两种方式表达的意思不一样,返回的数据也就不一样.

左连接有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)


相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
6月前
|
SQL
SQL FULL OUTER JOIN 关键字
【7月更文挑战第17天】SQL FULL OUTER JOIN 关键字。
49 6
|
6月前
|
SQL 数据库
SQL LEFT JOIN 关键字
【7月更文挑战第17天】SQL LEFT JOIN 关键字。
43 4
|
8月前
|
SQL 数据库
SQL HAVING 子句详解:在 GROUP BY 中更灵活的条件筛选
HAVING子句被添加到SQL中,因为WHERE关键字不能与聚合函数一起使用。
329 0
|
Shell
一.条件选择:if语句
一.条件选择:if语句
140 0
|
SQL 关系型数据库 MySQL
避免在where子句中使用 or 来连接条件
避免在where子句中使用 or 来连接条件
|
关系型数据库 MySQL
inner join 、left join、right join,优先使用inner join
inner join 、left join、right join,优先使用inner join
|
SQL 关系型数据库 MySQL
三、避免在where子句中使用 or 来连接条件
三、避免在where子句中使用 or 来连接条件
155 0
|
关系型数据库 MySQL
八、inner join 、left join、right join,优先使用inner join
八、inner join 、left join、right join,优先使用inner join
538 0
sql join中on条件后接and和where
sql join中on条件后接and和where
sql join中on条件后接and和where
|
关系型数据库 数据库
[20180625]10g下查询条件rownum = 0.txt
[20180625]10g下查询条件rownum = 0.txt SCOTT@test> @ &r/ver1 PORT_STRING                    VERSION        BANNER --------------------...
1174 0

热门文章

最新文章