为了账号安全,请及时绑定邮箱和手机立即绑定

在联接或位置内的条件

/ 猿问

在联接或位置内的条件

喵喵时光机 2019-07-15 10:39:17

在联接或位置内的条件

有什么不同(表现、最佳实践等.)在JOIN子句中添加条件与WHERE子句之间?

例如.。

-- Condition in JOINSELECT *FROM dbo.Customers AS CUSINNER JOIN dbo.Orders AS ORD 
ON CUS.CustomerID = ORD.CustomerIDAND CUS.FirstName = 'John'-- Condition in WHERESELECT *FROM 
dbo.Customers AS CUSINNER JOIN dbo.Orders AS ORD 
ON CUS.CustomerID = ORD.CustomerIDWHERE CUS.FirstName = 'John'

你喜欢哪一个(也许是为什么)?


查看完整描述

3 回答

?
泛舟湖上清波郎朗

关系代数允许在WHERE条款和INNER JOIN,所以甚至INNER JOIN查询WHERE子句可以使谓词由优化器重新排列,从而使它们可能已经被排除在外JOIN过程。

我建议您以最易读的方式编写查询。

有时,这包括使INNER JOIN相对“不完整”,并将一些标准放在WHERE只是为了使过滤条件列表更易于维护。

例如,而不是:

SELECT *FROM Customers cINNER JOIN CustomerAccounts ca    ON ca.CustomerID = c.CustomerID    
AND c.State = 'NY'INNER JOIN Accounts a    ON ca.AccountID = a.AccountID    AND a.Status = 1

写:

SELECT *FROM Customers cINNER JOIN CustomerAccounts ca    ON ca.CustomerID = c.CustomerIDINNER JOIN Accounts a  
  ON ca.AccountID = a.AccountIDWHERE c.State = 'NY'
    AND a.Status = 1

当然,这要视情况而定。


查看完整回答
反对 回复 2019-07-15
?
芜湖不芜

对于内部连接,我并没有真正注意到它们之间的区别(但是与所有性能调优一样,您需要在您的条件下对照数据库进行检查)。

然而,如果您使用的是左或右联接,则条件会产生巨大的不同。例如,考虑以下两个查询:

SELECT *FROM dbo.Customers AS CUS 
LEFT JOIN dbo.Orders AS ORD 
ON CUS.CustomerID = ORD.CustomerIDWHERE ORD.OrderDate >'20090515'SELECT *FROM dbo.Customers AS CUS 
LEFT JOIN dbo.Orders AS ORD 
ON CUS.CustomerID = ORD.CustomerIDAND ORD.OrderDate >'20090515'

第一个将只给出那些日期晚于2009年5月15日的订单记录,从而将左连接转换为内部连接。第二个会给出这些记录,再加上没有订单的任何客户。结果集非常不同,取决于您放置条件的位置。(如果仅选择*,则不应在生产代码中使用。)这种情况的例外情况是,您只希望在一个表中看到记录,而不希望看到另一个表中的记录。然后,对条件使用WHERE子句,而不是JOIN。

SELECT *FROM dbo.Customers AS CUS 
LEFT JOIN dbo.Orders AS ORD 
ON CUS.CustomerID = ORD.CustomerIDWHERE ORD.OrderID is null


查看完整回答
反对 回复 2019-07-15
?
慕函数4003404

大多数RDBMS产品将对这两个查询进行相同的优化。在PeterGulutzan和TrudyPelzer的“SQL性能调优”中,他们测试了多个品牌的RDBMS,发现性能没有差别。

我更喜欢将联接条件与查询限制条件分开。

如果你用OUTER JOIN有时,在JOIN子句中添加条件是必要的。


查看完整回答
反对 回复 2019-07-15

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信