Join 和 Natural Join 有什么区别?
What is the difference between Join and Natural Join?
我正在学习 Oracle SQL,现在我卡在了“连接”一章。我无法理解 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 Taylor 24/03/2006 31/12/2006
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 具有相似的功能,我不知道为什么会收到不同的结果。
不要使用 natural join
。这是一个等待发生的错误。
显式 join
有一个 on
子句,列出了表之间匹配的条件。在您的示例中,department_id
用于此目的(尽管其他列可能可用)。
using
子句是另一个非常有用的替代方法。您将其用作:
FROM employees e JOIN
job_history j
USING (department_id)
它在两个表中找到 department_id
并将其用于连接条件。
NATURAL JOIN
为表中 所有 列相同的列添加一个 JOIN
条件。在您的情况下,这将是 department_id
加上其他列 .
您遇到的问题是您不知道 join
使用了哪些列。更糟糕的是,显式 外键引用未被使用。
因为您的查询没有具体说明发生了什么,所以错误和错误的范围很大。 NATURAL JOIN
没有实际需要,所以你还不如学习使用 ON
和 USING
.
只是为了明确说明应该显而易见的事情:您的第一个查询产生了不同的结果,因为它在语义上与您的第二个查询不等同。
这里是 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;
上面的查询中没有 'bug waiting to happen',尽管我有 -- 震惊!恐怖! -- 除了 NATURAL JOIN
之外还使用了 SELECT *
(两者都被 SQL flock 所禁忌):在 CTE 中投影列可以保护您的查询免受向表中添加列的情况的影响 employees
和 job_history
.
我正在学习 Oracle SQL,现在我卡在了“连接”一章。我无法理解 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 Taylor 24/03/2006 31/12/2006
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 具有相似的功能,我不知道为什么会收到不同的结果。
不要使用 natural join
。这是一个等待发生的错误。
显式 join
有一个 on
子句,列出了表之间匹配的条件。在您的示例中,department_id
用于此目的(尽管其他列可能可用)。
using
子句是另一个非常有用的替代方法。您将其用作:
FROM employees e JOIN
job_history j
USING (department_id)
它在两个表中找到 department_id
并将其用于连接条件。
NATURAL JOIN
为表中 所有 列相同的列添加一个 JOIN
条件。在您的情况下,这将是 department_id
加上其他列 .
您遇到的问题是您不知道 join
使用了哪些列。更糟糕的是,显式 外键引用未被使用。
因为您的查询没有具体说明发生了什么,所以错误和错误的范围很大。 NATURAL JOIN
没有实际需要,所以你还不如学习使用 ON
和 USING
.
只是为了明确说明应该显而易见的事情:您的第一个查询产生了不同的结果,因为它在语义上与您的第二个查询不等同。
这里是 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;
上面的查询中没有 'bug waiting to happen',尽管我有 -- 震惊!恐怖! -- 除了 NATURAL JOIN
之外还使用了 SELECT *
(两者都被 SQL flock 所禁忌):在 CTE 中投影列可以保护您的查询免受向表中添加列的情况的影响 employees
和 job_history
.