SQL 自然连接查询未选择预期结果

SQL natural join query not selecting expected results

我正在尝试使用两个自然联接进行查询,但没有得到预期的结果。我想检索已分配项目的雇主数据。另外我想检索项目代码、项目名称和员工在项目上花费的时间。

这是我要进行的 SQL 查询:

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

这是 emp table:

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 table:

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

这就是专业人士 table:

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

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

谢谢。

NATURAL JOIN 只是一个等待发生的错误(在您的情况下可能正在发生)。它根据关联 tables/subqueries 中的 names 选择要加入的列。它甚至不使用声明的外键关系。对我来说似乎是个坏主意。只是忘记它的存在。

因此,请改用 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 ("keep all the rows in the first table and matching rows in the second").

没有人正是因为这些原因而使用 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

正如您在上面看到的,您不小心加入了碰巧出现在 emppro 中的 DEPTNO 列,但您不想加入那一栏。

以这种方式思考您的原始查询:

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

其中 A = (emp NATURAL RIGHT JOIN emppro)。因此,当将 pro 连接到 A 时,Apro 有两个共同点。