Junção Interna |
Sumário
A junção interna é uma operação de junção horizontal entre duas tabelas, que usa uma comparação por igualdade entre a(s) coluna(s) comum(ns). Normalmente a(s) coluna(s) comum(ns) é(são) Foreign Key numa tabela e Primary Key ou Unique Key na outra. A junção interna pode ser vista como um produto cartesiano filtrado, pois exige que as linhas da tabela da esquerda tenham correspondente na tabela da direita, sendo o valor da coluna comum igual. O diagrama apresentado a seguir mostra como funciona a junção interna entre duas tabelas:
A junção interna é a operação mais importante nas bases de dados relacionais, pelo que é suportada desde sempre. A norma SQL99 propos uma nova sintaxe para esta operação, tendo disponibilizado várias cláusulas que serão analisadas nos exemplos abaixo, onde também faremos a comparação com a sintaxe antiga. Os temas abordados serão:
As tabelas EMP e DEPT possuem uma relação entre si, implementada através da coluna comum DEPTNO. Na tabela EMP sabemos qual o número do departamento em que o empregado trabalha. Na tabela DEPT sabemos o número, nome e localização desse departamento. Para juntar os dois conjuntos efectuamos uma JUNÇÃO horizontal das duas tabelas, usando uma igualdade de valores na coluna comum, como ilustrado nos exemplos abaixo:
Sintaxe antiga | SQL99 |
---|---|
SELECT emp.empno, emp.ename, emp.deptno, dept.deptno, dept.dname, dept.loc FROM emp, dept WHERE emp.deptno=dept.deptno; |
SELECT emp.empno, emp.ename, emp.deptno, dept.deptno, dept.dname, dept.loc FROM emp INNER JOIN dept ON (emp.deptno=dept.deptno); |
EMPNO ENAME DEPTNO DEPTNO DNAME LOC ---------------------- ---------- ---------------------- ---------------------- -------------- ------------- 7369 SMITH 20 20 RESEARCH DALLAS 7499 ALLEN 30 30 SALES CHICAGO 7521 WARD 30 30 SALES CHICAGO 7566 JONES 20 20 RESEARCH DALLAS 7654 MARTIN 30 30 SALES CHICAGO 7698 BLAKE 30 30 SALES CHICAGO 7782 CLARK 10 10 ACCOUNTING NEW YORK 7788 SCOTT 20 20 RESEARCH DALLAS 7839 KING 10 10 ACCOUNTING NEW YORK 7844 TURNER 30 30 SALES CHICAGO 7876 ADAMS 20 20 RESEARCH DALLAS 7900 JAMES 30 30 SALES CHICAGO 7902 FORD 20 20 RESEARCH DALLAS 7934 MILLER 10 10 ACCOUNTING NEW YORK 14 rows selected |
A cláusula USING está disponível na sintaxe SQL99 e pode ser usada em vez da cláusula ON sempre que a(s) coluna(s) usada(s) na junção tenha(m) o mesmo nome em ambas as tabelas. Esta cláusula pode ser usada mesmo que existam outras colunas com o mesmo nome em ambas as tabelas.
No caso das tabelas EMP e DEPT a junção pode ser feita com USING:
Sintaxe antiga | SQL99 |
---|---|
SELECT emp.empno, emp.ename, emp.deptno, dept.deptno, dept.dname, dept.loc FROM emp, dept WHERE emp.deptno=dept.deptno; |
SELECT emp.empno, emp.ename, deptno, dept.dname, dept.loc FROM emp INNER JOIN dept USING (deptno); |
A cláusula NATURAL JOIN está disponível na sintaxe SQL99 e pode ser usada em vez da cláusula ON ou em vez da cláusula USING sempre que:
No caso das tabelas EMP e DEPT a junção pode ser feita com NATURAL JOIN:
Sintaxe antiga | SQL99 |
---|---|
SELECT emp.empno, emp.ename, emp.deptno, dept.deptno, dept.dname, dept.loc FROM emp, dept WHERE emp.deptno=dept.deptno; |
SELECT emp.empno, emp.ename, deptno, dept.dname, dept.loc FROM emp NATURAL JOIN dept; |
Comparação entre ON, USING e NATURAL JOIN
Consideremos as seguintes situações:
Situação | Modelo entidade relacionamento | Sintaxe antiga | ON | USING | NATURAL JOIN |
---|---|---|---|---|---|
1 |
SELECT * FROM t1, t2 WHERE t1.t1_c1=t2.t1_c1; |
SELECT * FROM t1 INNER JOIN t2 ON (t1.t1_c1=t2.t1_c1); |
SELECT * FROM t1 INNER JOIN t2 USING (t1_c1); |
SELECT * FROM t1 NATURAL JOIN t2; |
|
2 |
SELECT * FROM t3, t4 WHERE t3.t3_c1=t4.t3_c1 AND t3.t3_c2=t4.t3_c2; |
SELECT * FROM t3 INNER JOIN t4 ON (t3.t3_c1=t4.t3_c1 AND t3.t3_c2=t4.t3_c2); |
SELECT * FROM t3 INNER JOIN t4 USING (t3_c1,t3_c2); |
SELECT * FROM t3 NATURAL JOIN t4; |
|
3 |
SELECT * FROM t5, t6 WHERE t5.t5_c1=t6.t6_c2; |
SELECT * FROM t5 INNER JOIN t6 ON (t5.t5_c1=t6.t6_c2); |
Não é possível | Não é possível | |
4 |
SELECT * FROM t7, t8 WHERE t7.t7_c1=t8.t7_c1; |
SELECT * FROM t7 INNER JOIN t8 ON (t7.t7_c1=t8.t7_c1); |
SELECT * FROM t7 INNER JOIN t8 USING (t7_c1); |
Não é possível |
Sinónimos para nomes de tabelas
O nome da tabela pode ser substituído por um sinónimo, como mostram os exemplos abaixo:
Sintaxe antiga | SQL99 |
---|---|
SELECT e.empno, e.ename, e.deptno, d.deptno, d.dname, d.loc FROM emp e, dept d WHERE e.deptno=d.deptno; |
SELECT e.empno, e.ename, e.deptno, d.deptno, d.dname, d.loc FROM emp e INNER JOIN dept d ON (e.deptno=d.deptno); |
A utilização de sinónimos para os nomes das tabelas apresenta as seguintes vantagens:
Junção com mais de duas tabelas
A figura abaixo mostra as relações existentes entre as tabelas EMPLOYEES, DEPARTMENTS e LOCATIONS, pertencentes ao conjunto HR:
Este relacionamento possibilita a junção entre as 3 tabelas exemplificada pelos comandos abaixo:
Sintaxe antiga | ON | USING | NATURAL JOIN |
---|---|---|---|
SELECT e.first_name, e.last_name, d.department_id, d.department_name, l.city, l.state_province FROM employees e, departments d, locations l WHERE e.department_id=d.department_id AND d.location_id=l.location_id; |
SELECT e.first_name, e.last_name, d.department_id, d.department_name, l.city, l.state_province FROM employees e INNER JOIN departments d ON (e.department_id=d.department_id) INNER JOIN locations l ON (d.location_id=l.location_id); |
SELECT e.first_name, e.last_name, department_id, d.department_name, l.city, l.state_province FROM employees e INNER JOIN departments d USING (department_id) INNER JOIN locations l USING (location_id); |
Não é possível porque a coluna MANAGER_ID é comúm a Employees e a Departments e nao é usada na cláusula de junção deste relacionamento |
A cláusula de junção e a cláusula de filtro
O facto de efectuarmos uma junção entre duas tabelas não impede que se faça um filtro das linhas. O exemplo abaixo mostra como:
Sintaxe antiga | ON | USING | NATURAL JOIN |
---|---|---|---|
SELECT e.first_name, e.last_name, d.department_id, d.department_name FROM employees e, departments d WHERE e.department_id=d.department_id AND e.first_name like 'Jam%'; |
SELECT e.first_name, e.last_name, d.department_id, d.department_name FROM employees e INNER JOIN departments d ON (e.department_id=d.department_id) WHERE e.first_name like 'Jam%'; |
SELECT e.first_name, e.last_name, department_id, d.department_name FROM employees e INNER JOIN departments d USING (department_id) WHERE e.first_name like '%me%'; |
Não é possível porque a coluna MANAGER_ID é comúm a Employees e a Departments e nao é usada na cláusula de junção deste relacionamento |
A junção feita com colunas UNIQUE
As boas práticas recomendam que a junção entre duas tabelas seja feita entre a chave primária (PK - Primary Key) de uma e a chave estrangeira (FK - Foreign Key) da outra tabela. O motor relacional do Oracle permite que a chave primária seja substituída por uma chave alternativa. Por exemplo, em vez do número de empregado poderíamos usar o NIF (Número de Identificação Fiscal), desde que este seja único para cada empregado e tenha um valor não nulo. Para isto a base de dados requer a existência de um índice com a propriedade UNIQUE ou que seja definida a restrição UNIQUE sobre a(s) coluna(s) envolvida(s).
Realizado por Turtle Learning ®. Última alteração em 2011-02-26