2016-02-24 70 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

謝謝,非常好的提示申請! –