select d.department_id "Department Nummber", department_name,
nvl(last_name, 'NoManager!') "Manager",
job_id
from departments d left outer join employees e on (d.manager_id=e.employee_id)
natural join jobs j
order by 1;
我无法弄清楚上述查询的结果,执行时会返回11行。谜一点是,当从选择列表中删除“job_id”时,同一个查询返回513行,或者整个列表被替换为count(*),其中返回的行数也是513.
我认为这是导致无法解释的结果的自然联接,如替换
自然联接职位
带
使用(job_id)
加入作业
总是按预期产生11行,并“解决”问题。
我正在使用SQLDeveloper和Oracle Database 11g。我很感激有关这是怎么回事。
谢谢。
答案 0 :(得分:0)
我假设工作表与员工的工作表相关联。
Natural join
就像一个inner join
,因此您的left join
允许您显示"没有经理"结果(也许还有其他内容)但是natural/inner join
您正在将left join
转换为inner join
,因此删除所有未加入的左连接+没有工作的员工
您可以在作业上使用left join
或natural left join
。
答案 1 :(得分:0)
我永远不会使用自然联接 - 你发现的太容易出错(现在以一种我以前没有意识到的新方式!)
这里的问题是,您的查询中的自然联接在EMPLOYEES和JOBS之间不,但在结果之间
(select d.department_id "Department Nummber", department_name,
nvl(last_name, 'NoManager!') "Manager",
job_id
from departments d left outer join employees e on (d.manager_id=e.employee_id))
和JOBS。在这种情况下,有一个要连接的列:JOB_ID。
但是当您从SELECT中删除JOB_ID时,您现在正在加入两个"表"没有公共列(第一个"表"是自然连接之前的select语句)。而自然连接的一些反直觉(但完全"逻辑")行为是,如果没有公共列,那么它执行笛卡尔积!看到这个简单的例子:
SQL> select * from dept;
DEPTNO
----------
10
20
30
SQL> select * from jobs;
JOB_ID
----------
1000
2000
3000
SQL> select deptno, job_id from dept natural join jobs;
DEPTNO JOB_ID
---------- ----------
10 1000
10 2000
10 3000
20 1000
20 2000
20 3000
30 1000
30 2000
30 3000
9 rows selected.
为了获得您期望的行为,我认为您需要使用括号来获取适当的连接 - 例如:
select d.department_id "Department Nummber", department_name,
nvl(last_name, 'NoManager!') "Manager",
job_id
from departments d left outer join
(select * from employees e natural join jobs j) x
on d.manager_id=x.employee_id
order by 1;
或者更好:永远,永远在结果重要的查询中使用自然联接!