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语句有什么区别?
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
WHERE 将在 JOIN 发生后过滤。
select a.*,b.*
from A a left join B b
on a.id =b.id
where a.id=2;
id id
----------- -----------
2 2
select a.* from A a left join B b on a.id =b.id and a.id=2;
这仅a.id
在连接条件中使用,因此a.id <> 2
不会被过滤掉的记录。你可能会得到这样的结果:
+------+------+ | a.id | b.id | +------+------+ | 1 | 空 | | 2 | 2 | | 3 | 空 | +------+------+
您不选择任何b
' 列,但如果您这样做,它会更容易理解。
select a.* from A a left join B b on a.id =b.id where a.id=2;
现在记录a.id <> 2
被过滤掉的地方。
+------+------+ | a.id | b.id | +------+------+ | 2 | 2 | +------+------+
正如@hvd所说,“where”子句过滤连接返回的行,因此“where”版本不会返回外部连接的行(具有 a.id = null)。
然而,还有另一个显着的区别:即使外部连接的行没有被过滤掉,将条件放入“on”子句也可以大大提高性能,因为结果集更早地变小了。
当一系列其他左联接表跟随具有“and”条件的表时,这一点尤其明显 - 您甚至可以防止联接发生在以下表中以获取不合适的行,并可能切断数百万行到达过滤器(“where “) 阶段。
我尝试了一段时间,我知道是什么原因,它只与优先级有关。
select * from A a left join B b on a.id=b.id and b.id=2
这意味着 A 左连接(其中 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 过滤
如果您考虑 SQL 查询的语法,“AND”扩展了连接块(就像括号一样),其中“WHERE”定义了查询的 WHERE/过滤块的开始。
正如@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”为所有结果提供了条件。
说得更清楚一点,“WHERE”是从“ SELECT ”语句中找到结果后过滤掉结果集。“AND”是连接两个表的条件。