2010-04-27 54 views
34

下面的语句产生相同的结果(一个正在使用on,和其他使用where):在SQL/MySQL中,连接语句中的“ON”和“WHERE”有什么区别?

mysql> select * from gifts INNER JOIN sentGifts ON gifts.giftID = sentGifts.giftID; 
mysql> select * from gifts INNER JOIN sentGifts WHERE gifts.giftID = sentGifts.giftID; 

我可以在左外的情况下,只看到加入寻找“无与伦比”的情况:
(找出从未被任何人发来的礼物)

mysql> select name from gifts LEFT OUTER JOIN sentgifts 
      ON gifts.giftID = sentgifts.giftID 
      WHERE sentgifts.giftID IS NULL; 

在这种情况下,首先使用on,然后whereon是否先进行匹配,然后where进行“次要”过滤?还是有更一般的规则使用onwhere?谢谢。

+0

非常相似http://stackoverflow.com/questions/2559194/difference-between-and-and-where-in-joins – 2010-04-27 16:08:36

+1

这个问题有两个更好的标题。 – ripper234 2010-08-30 20:08:22

回答

38

WHERE是作为整体的SELECT查询的一部分,ON是每个单独连接的一部分。

ON只能引用先前使用的表的字段。

当与左表中的记录没有实际匹配时,LEFT JOIN从右表返回一条记录,所有字段均设置为NULLSWHERE子句然后评估并过滤此。

在您的查询中,只返回gifts中'sendgifts'不匹配的记录。

这里的例子

gifts 

1 Teddy bear 
2 Flowers 

sentgifts 

1 Alice 
1 Bob 

--- 
SELECT * 
FROM gifts g 
LEFT JOIN 
     sentgifts sg 
ON  g.giftID = sg.giftID 

--- 

1 Teddy bear 1  Alice 
1 Teddy bear 1  Bob 
2 Flowers  NULL NULL -- no match in sentgifts 

--- 
SELECT * 
FROM gifts g 
LEFT JOIN 
     sentgifts sg 
ON  g.giftID = sg.giftID 
WHERE sg.giftID IS NULL 

--- 

2 Flowers  NULL NULL -- no match in sentgifts 

正如你所看到的,没有实际的比赛能留在sentgifts.id一个NULL,所以只有那些没有曾经被送到返回的礼物。

0

如果您正在使用JOIN,则需要指定要加入的条件。该列表位于ON子句中。 WHERE子句用于为查询中的任何位置调整数据。

2

虽然结果相同,但'ON'首先使联接,然后检索联接的集合的数据。检索速度更快,负载更少。但是使用'WHERE'会导致首先获取两个结果集,然后应用该条件。所以你知道什么是首选。

11

当使用INNER JOIN时,ONWHERE将具有相同的结果。所以,

select * 
from Table1 t1 
inner join Table2 t2 on t1.id = t2.id 
where t1.Name = 'John' 

会有完全相同的输出

select * 
from Table1 t1 
inner join Table2 t2 on t1.id = t2.id 
    and t1.Name = 'John' 

正如你所提到的,使用OUTER JOIN当这种情况并非如此。构建哪个查询计划取决于数据库平台以及查询细节,并且可能会发生变化,因此仅凭这个基础做出决策并不能提供有保证的查询计划。

作为一个经验法则,您应该使用ON子句和列用于在WHERE子句中进行过滤的表格。这提供了最佳的可读性。

+0

使用“ON”与比field1 = field2更复杂的东西是否正确? – skan 2013-08-29 17:31:08

+0

是的,通常有多列ON子句。 – RedFilter 2013-08-29 17:36:11

+0

我的意思是,除了列比较之外,你还可以使用复杂的表达式吗? – skan 2013-08-29 22:04:03

40

ON子句定义了表之间的关系。

WHERE条款描述你是哪个行感兴趣。

很多时候,你可以交换他们仍然得到同样的结果,但是这并不总是与左外连接的情况。

  • 如果ON子句失败,您仍会得到一行左列中的列,但右列中的列中有空值。
  • 如果WHERE子句失败,则根本无法获得该行。
+0

Upvote for the last two statements – Sekai 2018-01-15 15:44:45

相关问题