使用Join而不是Subquery重写SQL代码

时间:2017-10-25 21:36:16

标签: sql database join

我无法直观地看到子查询如何以连接的形式出现。特别是,以下SQL:

SELECT DISTINCT e.EmployeeID, e.LastName, e.FirstName
FROM Employees e 
INNER JOIN Orders o ON e.EmployeeID = o.EmployeeID
WHERE EXISTS
(
  SELECT c.Country
  FROM Customers c
  WHERE c.Country = e.Country
)

如果我想要将带有子查询的语句转换为连接,我会收到一些关于该怎么做的提示,我将不胜感激。

2 个答案:

答案 0 :(得分:2)

您需要注意重复项,但EXISTS的转换非常直接:

SELECT DISTINCT e.EmployeeID, e.LastName, e.FirstName
FROM Employees e INNER JOIN
     Orders o
     ON e.EmployeeID = o.EmployeeID INNER JOIN
     (SELECT DISTINCT c.Country
      FROM Customers c
     ) c
     ON  c.Country = e.Country

答案 1 :(得分:-1)

这看起来很干净。事实上,它不是:

SELECT DISTINCT e.EmployeeID, e.LastName, e.FirstName
FROM Employees e
JOIN Orders o ON o.EmployeeID = e.EmployeeID
JOIN Customers c ON c.Country = e.Country
        ;

重点是,如果ordersCustomers有多个匹配行,则这些行将导致合并Employee记录的单独副本。这些后来必须被DISTINCT抑制(优化者可能会捕获这个,或者它可能不会)

关键是:你不需要一个独特的,因为你只是从员工中选择列:

SELECT e.EmployeeID, e.LastName, e.FirstName
FROM Employees e 
WHERE EXISTS( 
  SELECT * FROM Orders o
  WHERE o.EmployeeID = e.EmployeeID
  )
AND EXISTS(
  SELECT * FROM Customers c
  WHERE c.Country = e.Country
  );

或者,或多或少丑陋的风格

SELECT e.EmployeeID, e.LastName, e.FirstName
FROM Employees e 
WHERE EXISTS(
  SELECT c.Country
  FROM Orders o
  JOIN Customers c
  ON o.EmployeeID = e.EmployeeID
  AND c.Country = e.Country
);