3

我正在学习 Oracle SQL,现在我被困在 Joins 章节中。我无法理解 Join 和 Natural Join 之间的区别

SELECT         employee_id, job_id, department_id,
               e.last_name, e.hire_date, j.end_date
FROM           employees e
NATURAL JOIN   job_history j;

176 SA_REP 80 泰勒 2006 年 3 月 24 日 2006 年 12 月 31 日

SELECT         e.employee_id, e.job_id, e.department_id,
               e.last_name, e.hire_date, j.end_date
FROM           employees e
JOIN           job_history j
ON             (e.department_id = j.department_id)
ORDER BY        employee_id, last_name;

172 SA_REP  80  Bates   24/03/2007  31/12/2006
173 SA_REP  80  Kumar   21/04/2008  31/12/2007
173 SA_REP  80  Kumar   21/04/2008  31/12/2006
174 SA_REP  80  Abel    11/05/2004  31/12/2007
174 SA_REP  80  Abel    11/05/2004  31/12/2006
175 SA_REP  80  Hutton  19/03/2005  31/12/2007
175 SA_REP  80  Hutton  19/03/2005  31/12/2006
176 SA_REP  80  Taylor  24/03/2006  31/12/2007
176 SA_REP  80  Taylor  24/03/2006  31/12/2006
177 SA_REP  80  Livingston  23/04/2006  31/12/2007
177 SA_REP  80  Livingston  23/04/2006  31/12/2006

如果 Join 和 Natural Join 都具有相似的功能,我不知道为什么会收到不同的结果。

4

2 回答 2

10

不要使用natural join. 这是一个等待发生的错误。

显式join具有on列出表之间匹配条件的子句。在您的示例中,department_id是出于此目的(尽管其他列可能可用)。

using子句是另一个非常有用的替代方案。您将其用作:

FROM employees e JOIN
     job_history j
     USING (department_id)

department_id在两个表中都找到并将其用于连接条件。

NATURAL JOIN为表中所有相同的列添加JOIN条件。在您的情况下,这将是plus other columnsdepartment_id

问题 - 正如您所遇到的那样 - 是您不知道join. 更糟糕的是,没有使用显式外键引用。

因为您的查询没有指定正在发生的事情,所以有很多错误和错误的范围。没有实际需要NATURAL JOIN,所以你不妨学习使用ONand USING

于 2017-01-11T02:51:58.460 回答
2

只是为了明确什么应该是显而易见的:您的第一个查询会产生不同的结果,因为它在语义上不等同于您的第二个查询。

以下是该NATURAL JOIN版本的建议重写:

WITH e AS 
     ( SELECT employee_id, job_id, department_id,
              last_name, hire_date
         FROM employees ),
     j AS 
     ( SELECT department_id, end_date
         FROM job_history )
SELECT * 
  FROM e NATURAL JOIN j
 ORDER 
    BY employee_id, last_name;

上面的查询中没有“等待发生的错误”,即使我有——震惊!恐怖!-SELECT *除了使用NATURAL JOIN(两者都被 SQL 群禁止):在 CTE 中投影列可以保护您的查询免受将列添加到表employeesjob_history.

于 2017-02-02T15:04:51.527 回答