SQL em Oracle > DML > Junção de tabelas > Junção Horizontal > Equi-junção
Junção Interna tl_logo2.jpg

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:

JuncaoInner.jpg

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:


Cláusula ON

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

bthome.gifTopo


Cláusula USING

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);

bthome.gifTopo


Cláusula NATURAL JOIN

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;

bthome.gifTopo


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 ex1.jpg
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 ex2.jpg
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 ex3.jpg
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 ex4.jpg
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

bthome.gifTopo


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);

note04.gif A utilização de sinónimos para os nomes das tabelas apresenta as seguintes vantagens:

bthome.gifTopo


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

bthome.gifTopo


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

bthome.gifTopo


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).

bthome.gifTopo


Realizado por Turtle Learning ®. Última alteração em 2011-02-26