sql - NATURAL JOIN 和 USING 子句的意外结果
问题描述
所以我正在学习如何从多个表中获取数据,并且我对 NATURAL JOIN 和 USING 子句有疑问。所以我有 2 个要从中提取数据的表;员工和部门。
SQL> describe employees
Name Null? Type
----------------------------------------- -------- ------------------------
EMPLOYEE_ID NUMBER(6)
FIRST_NAME VARCHAR2(20)
LAST_NAME NOT NULL VARCHAR2(25)
EMAIL NOT NULL VARCHAR2(25)
PHONE_NUMBER VARCHAR2(20)
HIRE_DATE NOT NULL DATE
JOB_ID NOT NULL VARCHAR2(10)
SALARY NUMBER(8,2)
COMMISSION_PCT NUMBER(2,2)
MANAGER_ID NUMBER(6)
DEPARTMENT_ID NUMBER(4)
SQL> describe departments
Name Null? Type
----------------------------------------- -------- ------------------------
DEPARTMENT_ID NOT NULL NUMBER(4)
DEPARTMENT_NAME VARCHAR2(30)
MANAGER_ID NUMBER(6)
LOCATION_ID NUMBER(4)
当我在两个不同的表达式中使用 NATURAL JOIN 和 USING 时,我有两个不同的输出。我知道 USING 专门匹配两个表中的一列,但这对输出有何影响?与 NATURAL JOIN 相比,使用 USING 的表达式为什么会产生一个额外的值?
SELECT department_id, manager_id, last_name, location_id
FROM employees NATURAL JOIN departments
WHERE department_id = 80
ORDER BY location_id desc;
DEPARTMENT_ID MANAGER_ID LAST_NAME LOCATION_ID
------------- ---------- ------------------------- -----------
80 149 Abel 2500
80 149 Grant 2500
80 149 Taylor 2500
SELECT department_id, departments.manager_id, last_name, location_id
FROM employees JOIN departments
USING (department_id)
WHERE department_id = 80
ORDER BY location_id desc;
DEPARTMENT_ID MANAGER_ID LAST_NAME LOCATION_ID
------------- ---------- ------------------------- -----------
80 149 Zlotkey 2500 <-Additional Line*
80 149 Grant 2500
80 149 Taylor 2500
80 149 Abel 2500
任何帮助和建议表示赞赏!
解决方案
因为 NATURAL JOIN 连接所有具有相同名称的列,因此您的 NJ 查询也将连接 manager_id,而 USING 表单不会
如果您检查 USING 表单,您会发现每个表中的 manager_id 是不同的。(进行查询SELECT *
,您会看到..)
当自然加入这两个表之间的 manager_id 差异时,将从结果中删除该行
可能值得注意的是,自然连接和使用应该很少使用。一定要了解它们,这样你才能欣赏它们的存在,但你应该坚持使用常规的显式连接,以保持一致和清晰的行为 - 如果应用程序将来升级并且两个新列添加到这两个表中,命名相同但不同的数据新泽西州会失败。
编辑:
运行这个:
SELECT *
FROM employees JOIN departments
USING (department_id)
WHERE department_id = 80
ORDER BY location_id desc;
查看显示经理 ID 的两列。Zlotkey 行上的数据会有所不同
你自然加入有效地做到了这一点:
SELECT *
FROM employees e JOIN departments d
on e.department_id = d.department_id AND e.manager_id = d.manager_id
WHERE department_id = 80
ORDER BY location_id desc;
并且on e.department_id = d.department_id AND e.manager_id = d.manager_id
对于 zlotkey 行不正确
这就是自然连接有风险并且可能无用的原因——仅仅因为两列具有相同的名称并不意味着它们中的数据是相关的。事实上,在你的情况下,你的部门有经理,你的员工有经理。我的工作中也有这种设置,但是我的经理不是我所在部门的经理
推荐阅读
- java - 如何使用 Firebase 搜索查询结果项实现 OnClick 项
- entity-framework - 如何使用 Fluent Api 使我的结构与 EF Core 一起工作?
- ssl - 检查 API 协议以确保没有停机时间
- javascript - HTML选择下拉列表如何显示VALUE/ID而不是文本
- acumatica - 如何从重定向页面刷新网格
- python - Python:如果列具有键值对格式的数据,如何读取 csv 数据
- c++ - C++:如何从另一个谓词定义一个泛型非谓词
- c# - 使用注入的记录器登录类
- javascript - 在 ASP.NET MVC 中解析莫里斯图的数据
- java - 从反应堆级别运行时的 Maven 强制执行器问题