2016-02-24 74 views
0

我试图用两个自然连接进行查询,但是我没有得到预期的结果。我想检索具有分配项目的雇主数据。此外,我想检索项目代码,项目名称和员工花费在项目上的时间。SQL自然连接查询没有选择预期的结果

这是SQL查询我试图让:

SELECT empno, ename, sal, prono, hours, pname 
FROM emp NATURAL RIGHT JOIN emppro NATURAL JOIN pro; 

这是EMP表:

EMPNO ENAME JOB   MGR HIREDATE  SAL  COMM DEPTNO 
----- ---------- --------- ----- -------- ------- ------- ------ 
7369 SMITH CLERK  7902 17/12/80  800    20 
7499 ALLEN SALESMAN 7698 20/02/81 1,600  300  30 
7521 WARD SALESMAN 7698 22/02/81 1,250  500  30 
7566 JONES MANAGER 7839 02/04/81 2,975    20 
7654 MARTIN SALESMAN 7698 28/09/81 1,250  1,400 30 
7698 BLAKE MANAGER 7839 01/05/81 2,850    30 
7782 CLARK MANAGER 7839 09/06/81 2,450    10 
7788 SCOTT ANALYST 7566 19/04/87 3,000    20 
7839 KING PRESIDENT 17/11/81  5,000    10 
7844 TURNER SALESMAN 7698 08/09/81 1,500  0  30 
7876 ADAMS CLERK  7788 23/05/87 1,100    20 
7900 JAMES CLERK  7698 03/12/81  950    30 
7902 FORD ANALYST 7566 03/12/81 3,000    20 
7934 MILLER CLERK  7782 23/01/82 1,300    10 

这是emppro表:

EMPNO  PRONO  HOURS 
----- ---------- ---------- 
7499  1004  15 
7499  1005  12 
7521  1004  10 
7521  1008  8 
7654  1001  16 
7654  1006  15 
7654  1008  5 
7844  1005  6 
7934  1001  4 

而且这是亲表:

PRONO  PNAME  LOC   DEPTNO 
---------- ---------- ------------- ------ 
1001  P1   BOSTON   20 
1004  P4   CHICAGO  30 
1005  P5   CHICAGO  30 
1006  P6   LOS ANGELES 30 
1008  P8   NEW YORK  30 

如果我使用内部连接进行查询,它可以正常工作,为什么?我认为我不能正确理解自然连接...

谢谢。

回答

2

没有人正是因为这些原因使用NATURAL JOIN。您的疑问:

SELECT empno, ename, sal, prono, hours, pname 
FROM emp NATURAL RIGHT JOIN emppro NATURAL JOIN pro; 

等效于此查询:

SELECT empno, ename, sal, prono, hours, pname 
FROM emp 
RIGHT JOIN emppro ON emp.empno = emppro.empno 
JOIN pro ON emppro.prono = pro.prono 
    AND emp.deptno = pro.deptno -- This predicate is completely unexpected and wrong 

正如你可以在上面看到,你不小心参加过DEPTNO列碰巧同时存在于emppro,但你没不想加入这个专栏。

想想你的原始查询是这样的:

SELECT empno, ename, sal, prono, hours, pname 
FROM A NATURAL JOIN pro; 

哪里A = (emp NATURAL RIGHT JOIN emppro)。所以,当加入proA时,有两列Apro有共同点。

+0

谢谢! Cleary的答案,我没有意识到这个错误。所以当我使用自然连接时,它会匹配所有具有相同名称的列,对吗?我认为它只与前面的表匹配。 –

+0

是:所有具有相同名称的列。我会更新答案并解释原因。 –

+0

好的,我明白了。非常清楚的解释,谢谢! –

1

NATURAL JOIN只是一个等待发生的错误(正如大概发生在你的情况)。它根据关联的表/子查询中的名称选择要加入的列。它甚至不使用已声明的外键关系。对我来说,这似乎是一个非常糟糕的主意。只要忘记它存在。

因此,请使用USING代替(或者如果您更喜欢ON)。就像这样:

SELECT empno, ename, sal, prono, hours, pname 
FROM emp RIGHT JOIN emppro 
    emppro 
    USING (EMPNO) INNER JOIN 
    pro 
    USING (PRONO); 

我不是RIGHT JOIN的粉丝。我认为LEFT JOIN更容易遵循逻辑,特别是如果你正在学习SQL(“保留第一个表中的所有行和第二个中匹配的行”)。

+0

谢谢,非常好的提示申请! –