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)
时间: 2024-10-29 11:58:46

JOIN ON 和 WHERE 条件的相关文章

对 DB2 星形模式查询启用 zigzag join

简介 本文讨论一个分析过程,它将帮助您理解 zigzag 计划,将该计划用于拥有星形模式设计的数据库中的星形查询.您将能够解释优化器计划和检查解释输出,从而查看用于执行一个查询的 zigzag join 的详细信息.您还能够在索引建议器的帮助下,使用事实表上的多列索引排除问题. 星形模式 星形模式是一种用于数据仓库的,范规范化模式架构.星形模式由一些引用任意数量的维度表的事实表(通常为一个)组成. 事实表包含主要数据,而较小的维度表描述了维度的每个值. 维度表有一个简单的主键,而事实表有一个由相

SparkSQL – 有必要坐下来聊聊Join

Join背景介绍 Join是数据库查询永远绕不开的话题,传统查询SQL技术总体可以分为简单操作(过滤操作-where.排序操作-limit等),聚合操作-groupBy等以及Join操作等.其中Join操作是其中最复杂.代价最大的操作类型,也是OLAP场景中使用相对较多的操作.因此很有必要聊聊这个话题. 另外,从业务层面来讲,用户在数仓建设的时候也会涉及Join使用的问题.通常情况下,数据仓库中的表一般会分为"低层次表"和"高层次表". 所谓"低层次表&q

SQL语句的并集UNION 交集JOIN(内连接,外连接)等介绍_MsSql

1. a. 并集UNION SELECT column1, column2 FROM table1 UNION SELECT column1, column2 FROM table2 b. 交集JOIN SELECT * FROM table1 AS a JOIN table2 b ON a.name=b.name c. 差集NOT IN SELECT * FROM table1 WHERE name NOT IN(SELECT name FROM table2) d. 笛卡尔积 SELECT

数据蒋堂 | JOIN运算剖析

JOIN是SQL中用于多表关联的运算,无论从程序员编写还是数据库实现角度来看,JOIN都是SQL中最难的运算. 其实,SQL对JOIN的定义非常简单,就是对两个集合(表)做笛卡尔积后再按某种条件过滤,写出来的语法也就是A JOIN B ON ...的形式.原则上,笛卡尔积后的结果集应当是以两集合成员构成的二元组为成员,不过由于SQL中的集合成员总是有字段的记录,而且也不支持泛型数据类型来描述成员为记录的二元组,所以就简单地把结果集处理成由两表记录的字段合并后构成的新记录集合.这也是JOIN一词在

【数据蒋堂】第29期:JOIN运算剖析

JOIN是SQL中用于多表关联的运算,无论从程序员编写还是数据库实现角度来看,JOIN都是SQL中最难的运算. 其实,SQL对JOIN的定义非常简单,就是对两个集合(表)做笛卡尔积后再按某种条件过滤,写出来的语法也就是A JOIN B ON ...的形式.原则上,笛卡尔积后的结果集应当是以两集合成员构成的二元组为成员,不过由于SQL中的集合成员总是有字段的记录,而且也不支持泛型数据类型来描述成员为记录的二元组,所以就简单地把结果集处理成由两表记录的字段合并后构成的新记录集合.这也是JOIN一词在

Select语句,join,union用法

一.基本的SELECT语句     1. "*"的注意事项:在SELECT语句中,用*来选取所有的列,这是一个应该抵制的习惯.     虽然节省了输入列名的时间,但是也意味着获得的数据比真正需要的数据多的多.相应的,也会降低应用程序的性能及网络性能.     良好的规则是只选所需.     2. join子句     jion是用来定义如何从多个表中选取数据并组合成一个结果集.     jion必需是因为(1)我们所要获取的所有信息并不都在一个表中,或者(2)所要返回的信息都在一个表中

SQL中JOIN和UNION区别、用法及示例介绍_MsSql

1.JOIN和UNION区别 join 是两张表做交连后里面条件相同的部分记录产生一个记录集, union是产生的两个记录集(字段要一样的)并在一起,成为一个新的记录集 . JOIN用于按照ON条件联接两个表,主要有四种: INNER JOIN:内部联接两个表中的记录,仅当至少有一个同属于两表的行符合联接条件时,内联接才返回行.我理解的是只要记录不符合ON条件,就不会显示在结果集内. LEFT JOIN / LEFT OUTER JOIN:外部联接两个表中的记录,并包含左表中的全部记录.如果左表

MySQL左联多表查询where条件写法示例_Mysql

复制代码 代码如下: select * from _test a left join _test b on a.id=b.id where a.level='20' and a.month='04' and b.level='20' and b.month='03'; select a.*,b.* from (select * from _test where level='20' and month='04') as a left join (select * from _test where

SQL高级查询技巧(两次JOIN同一个表,自包含JOIN,不等JOIN)

掌握了这些,就比较高级啦 Using the Same Table Twice 如下面查询中的branch字段 SELECT a.account_id, e.emp_id, b_a.name open_branch, b_e.name emp_branch FROM account AS a INNER JOIN branch AS b_a ON a.open_branch_id = b_a.branch_id INNER JOIN employee AS e ON a.open_emp_id