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语句的区别是什么?
答案 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 /过滤块的开头。