我必须将旧查询从已弃用的*=转换为左连接语句。我不是特别熟悉旧的运算符,我不确定我试图转换的查询是否写得很糟糕,或者这是否是正确的符号。我来解释一下我的意思:
SELECT GivenName, Surname, OrderNumber
FROM Customers, SalesOrders
WHERE Customers.ID *= SalesOrders.CustomerID
and SalesOrders.OrderNumber = 1000 -- ???
OrderNumber = 1000是左连接的一部分吗?如果OrderNumber不是左连接的一部分,那么使用*=操作符似乎没有意义。
或者,换句话说,这是等效的代码:
SELECT GivenName, Surname, OrderNumber
FROM Customers LEFT JOIN SalesOrders
ON Customers.ID = SalesOrders.CustomerID
and SalesOrders.OrderNumber = 1000
或
SELECT GivenName, Surname, OrderNumber
FROM Customers LEFT JOIN SalesOrders
ON Customers.ID = SalesOrders.CustomerID
WHERE SalesOrders.OrderNumber = 1000
在第二个查询中,左连接仍然是没有意义的。
回答我自己的问题-在找到旧环境后-感谢Gordon的建议-
SELECT GivenName, Surname, OrderNumber
FROM Customers, SalesOrders
WHERE Customers.ID *= SalesOrders.CustomerID
and SalesOrders.OrderNumber = 1000
是正确的,与
等价SELECT GivenName, Surname, OrderNumber
FROM Customers LEFT JOIN SalesOrders
ON Customers.ID = SalesOrders.CustomerID
and SalesOrders.OrderNumber = 1000
在这种特殊情况下,所有3个代码块将生成相同的执行计划并提供相同的结果。
*=
表示LEFT
,=
表示INNER
。
我假设我们永远不会知道原始需求,但在这种情况下,LEFT
与INNER
的选择并不取决于OrderNumber = 1000
条件,无论如何你必须使用LEFT
连接。
这是一个可读性问题,将过滤器与连接条件分开是一个很好的实践,特别是在多个表连接的情况下。所以只要在WHERE
中加入过滤器,在ON
子句中加入连接条件就可以避免当你不知道是join的一部分还是WHERE"所以最后一个代码块看起来很好。
类似情况的一个很好的描述:https://stackoverflow.com/a/2510059/3441990
您可以在这里找到更多关于遗留连接语法的信息:旧式外部连接已经过时