在JOIN子句和WHERE子句中添加条件之间有什么区别?

  • 回答 (2)
  • 关注 (0)
  • 查看 (14)

在JOIN子句和WHERE子句中添加条件之间有什么区别?

例如

-- Condition in JOIN
SELECT *
FROM dbo.Customers AS CUS
INNER JOIN dbo.Orders AS ORD 
ON CUS.CustomerID = ORD.CustomerID
AND CUS.FirstName = 'John'

-- Condition in WHERE
SELECT *
FROM dbo.Customers AS CUS
INNER JOIN dbo.Orders AS ORD 
ON CUS.CustomerID = ORD.CustomerID
WHERE CUS.FirstName = 'John'

炜炜炜炜提问于
我贼迷美丽策回答于
已采纳

关系代数允许WHERE子句和子句中谓词的可交换性INNER JOIN,所以即使INNER JOIN带有WHERE子句的查询也可以使谓词由优化器重新排列,以便在此过程中它们可能已被排除JOIN

我建议你尽可能以最可读的方式编写查询。

有时候,这包括使INNER JOIN相对“不完整”,并将一些标准放在WHERE简单的过滤条件列表中,以便更容易维护。

例如,而不是:

SELECT *
FROM Customers c
INNER 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 c
INNER JOIN CustomerAccounts ca
    ON ca.CustomerID = c.CustomerID
INNER JOIN Accounts a
    ON ca.AccountID = a.AccountID
WHERE c.State = 'NY'
    AND a.Status = 1
MyLove回答于

对于内部连接,我没有真正注意到其中的差异(但是与所有性能调整一样,需要在你的条件下检查数据库)。

但是,如果使用左连接或右连接,那么放置条件会产生巨大差异。例如考虑这两个查询:

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

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

第一个将只给你那些订单日期晚于2009年5月15日的记录,从而将左连接转换为内连接。第二个将给这些记录加上任何没有订单的客户。结果集根据您放置条件的位置而有很大不同。(如果仅出于示例目的,请选择*,当然,您不应该在生产代码中使用)。例外情况是,你只想查看一个表中的记录,而不是另一个表中的记录。然后你使用where子句作为条件而不是连接。

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

扫码关注云+社区