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
正如您在上面看到的,您不小心加入了碰巧出现在 emp
和 pro
中的 DEPTNO
列,但您不想加入那一栏。
以这种方式思考您的原始查询:
SELECT empno, ename, sal, prono, hours, pname
FROM A NATURAL JOIN pro;
其中 A = (emp NATURAL RIGHT JOIN emppro)
。因此,当将 pro
连接到 A
时,A
和 pro
有两个共同点。
我正在尝试使用两个自然联接进行查询,但没有得到预期的结果。我想检索已分配项目的雇主数据。另外我想检索项目代码、项目名称和员工在项目上花费的时间。
这是我要进行的 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
正如您在上面看到的,您不小心加入了碰巧出现在 emp
和 pro
中的 DEPTNO
列,但您不想加入那一栏。
以这种方式思考您的原始查询:
SELECT empno, ename, sal, prono, hours, pname
FROM A NATURAL JOIN pro;
其中 A = (emp NATURAL RIGHT JOIN emppro)
。因此,当将 pro
连接到 A
时,A
和 pro
有两个共同点。