在SQL/MySQL中,连接语句中"ON"和"WHERE"之间有什么区别?

nop*_*ole 46 mysql sql join where-clause

以下语句给出相同的结果(一个使用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;
Run Code Online (Sandbox Code Playgroud)

我只能在左外连接的情况下看到"无与伦比"的案例:(
找出任何人从未发过的礼物)

mysql> select name from gifts LEFT OUTER JOIN sentgifts 
           ON gifts.giftID = sentgifts.giftID 
           WHERE sentgifts.giftID IS NULL;
Run Code Online (Sandbox Code Playgroud)

在这种情况下,它首先使用on,然后where.是否on先做匹配,然后where做"辅助"过滤?或者是否有更一般的使用on对比规则where?谢谢.

Mar*_*ers 49

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

WHERE子句描述了您感兴趣的行.

很多时候你可以交换它们并仍然得到相同的结果,但是对于左外连接并不总是如此.

  • 如果该ON子句失败,您仍然会从左表中获取一行,但右表中的列中包含空值.
  • 如果该WHERE条款失败,则根本不会获得该行.


Qua*_*noi 48

WHERESELECT整个查询ON的一部分,是每个单独连接的一部分.

ON 只能引用以前使用的表的字段.

如果与左表中的记录没有实际匹配,则从右表LEFT JOIN返回一个记录,并将所有字段设置为NULLS.WHERE然后,子句对此进行评估和过滤.

在您的查询中,仅gifts返回"sentgifts"中不匹配的记录.

这是一个例子

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
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,没有实际的比赛可以留下NULLsentgifts.id,所以只有那些没有曾经被送到返回的礼物.


Red*_*ter 14

当使用INNER JOIN,ON并且WHERE将具有相同的结果.所以,

select *
from Table1 t1
inner join Table2 t2 on t1.id = t2.id
where t1.Name = 'John'
Run Code Online (Sandbox Code Playgroud)

将具有完全相同的输出

select *
from Table1 t1
inner join Table2 t2 on t1.id = t2.id
    and t1.Name = 'John'
Run Code Online (Sandbox Code Playgroud)

如您所知,使用时情况并非如此OUTER JOIN.构建什么查询计划取决于数据库平台以及查询细节,并且可能会发生变化,因此仅在此基础上做出决策并不能提供有保证的查询计划.

根据经验,您应该使用在ON用于过滤WHERE子句的子句和列中连接表的列.这提供了最佳的可读性.


Kan*_*kan 5

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