SQL左连接中“on ..和”与“on .. where”之间的区别?

时间:2012-09-13 06:26:14

标签: sql join syntax where

Sql语句。

1.select a.* from A a left join B b on a.id =b.id and a.id=2;

2.select a.* from A a left join B b on a.id =b.id where a.id=2;

这两个sql语句的区别是什么?

6 个答案:

答案 0 :(得分:28)

create table A(id int);
create table B(id int);

INSERT INTO A VALUES(1);
INSERT INTO A VALUES(2);
INSERT INTO A VALUES(3);

INSERT INTO B VALUES(1);
INSERT INTO B VALUES(2);
INSERT INTO B VALUES(3);

SELECT * FROM A;
SELECT * FROM B;

id
-----------
1
2
3

id
-----------
1
2
3

过滤JOIN以防止在JOIN过程中添加行。

select a.*,b.*
from   A a left join B b 
on     a.id =b.id and a.id=2;

id          id
----------- -----------
1           NULL
2           2
3           NULL

JOIN发生后将在哪里过滤。

select a.*,b.* 
from   A a left join B b 
on     a.id =b.id 
where  a.id=2;

id          id
----------- -----------
2           2

答案 1 :(得分:9)

  

从a a左侧连接B b中选择a。* a.id = b.id和a.id = 2;

这仅在加入条件中使用a.id,因此记录a.id <> 2未被过滤掉的记录。你可能会得到这样的结果:

+------+------+
| a.id | b.id |
+------+------+
| 1    | NULL |
| 2    | 2    |
| 3    | NULL |
+------+------+

您没有选择任何b列,但如果您这样做,则会更容易理解。

  

从a左侧连接B b中选择a。* a.id = b.id,其中a.id = 2;

现在记录过滤掉a.id <> 2的位置。

+------+------+
| a.id | b.id |
+------+------+
| 2    | 2    |
+------+------+

答案 2 :(得分:1)

@mr_eclair明确解释了

在两种情况下都会发生什么。 让我告诉你一个简单的方法来记住这一点。

select a.*,b.*
from   A a left join B b 
**on**     a.id =b.id ***and*** a.id=2;

“ AND”在“ ON”上起作用,它为加入条件提供了条件。

select a.*,b.* 
from   A a left join B b 
on     a.id =b.id 
**where**  a.id=2;

此处“ WHERE”为所有结果提供了条件。

更清楚地说, 从“ SELECT ”语句中找到结果后,“ WHERE”过滤出结果集。 “ AND”是连接两个表的条​​件。

答案 3 :(得分:0)

@hvd所述,“where”子句过滤连接返回的行,因此“where”版本不会返回外连接的行(具有a.id = null)。

然而,还有另一个显着的区别:即使外部连接的行没有被过滤掉,也可以通过将条件置于“on”子句中进行大规模的性能提升,因为结果集会更早地变小。

当一系列其他左连接表跟随具有“和”条件的表时,这一点尤其明显 - 您可以阻止连接发生到下面的表中,以获得不合适的行,并可能阻止数百万行到达过滤(“哪里”)阶段。

答案 4 :(得分:0)

我尝试了一段时间,我知道原因是什么,它只与优先级有关。

select * from A a left join B b on a.id=b.id and b.id=2

这意味着左连接(其中b.id = 2)这是条件  首先过滤B

Select * from A a left join B b on a.id=b.id where a.id=2

这意味着在加入B之后,然后按a.id = 2

过滤

答案 5 :(得分:0)

如果考虑SQL查询的语法,'AND'会扩展连接块(就像括号一样),其中'WHERE'定义了查询的WHERE /过滤块的开头。