我使用的是Oracle数据库,但我也检查了PostgreSQL上的场景。我创建了两个表:
CREATE TABLE departments (
dept_id INT PRIMARY KEY,
dept_name VARCHAR(255)
);
和
CREATE TABLE employees (
emp_id INT PRIMARY KEY,
emp_name VARCHAR(255),
department_id INT,
FOREIGN KEY (department_id) REFERENCES departments(dept_id)
);
如您所见,department 表中的外键列名为department_id,数据类型为INT,而employees 表中的引用列名为dept_id,数据类型为INT。它们既不具有相同的名称,也不具有相同的数据类型。
然后我写了这个自然连接语句:
SELECT * FROM employees
NATURAL JOIN departments;
令人惊讶的是,它给了我结果而不是错误。考虑到定义,人们自然会预期在这种情况下会出现错误。
所以,我想可能是因为外键引用,所以我删除了它:
ALTER TABLE employees
DROP CONSTRAINT SYS_C008253;
然后我再次运行相同的查询,它再次提供结果而不是错误。
我的问题是,为什么我得到结果而不是错误?定义中说NATURAL JOIN需要同名的列,所以应该会出现错误,对吧?
natural join
纯粹基于列names,而不考虑任何实际的外键引用。在这里,它找不到匹配的列名称,并且 - 类似于在 where
中省略条件列表的方式,如 where true
- join
没有条件,如 join...on true
。它甚至在文档中也是这样写的:
是NATURAL
的简写形式:它形成一个USING
列表,其中包含两个输入表中出现的所有列名称。与USING
一样,这些列在输出表中仅出现一次。如果没有公共列名称,USING
的行为类似于NATURAL JOIN
,产生叉积连接。JOIN ... ON TRUE
所以你最终会得到同样的东西a
cross join
,逗号,
,a join...on true
会得到你,所有这些都是完全有效。