Você está na página 1de 13

Exibio de Dados de Vrias Tabelas

PARTE I
Conteudista
Prof. Me. MARCUS ROGERIO OLIVEIRA

SQL FUNDAMENTALS I E PROGRAM WITH


PL/SQL
1

Unidade 2 - Exibio de Dados de Vrias Tabelas


1.1 Conceitos Bsicos

A juno (join) uma consulta que combina linhas de duas ou mais tabelas, views ou views
materializadas. O Oracle Database realiza uma juno sempre que mltiplas tabelas aparecem
na clusula FROM da consulta. A lista de seleo da consulta pode selecionar todas as colunas
de qualquer uma dessas tabelas. Se duas dessas tabelas tm um nome de coluna em comum,
ento o usurio deve qualificar todas as referncias a essas colunas em toda a consulta com o
nome da respectiva tabela, para evitar ambiguidade.

1.2 Condies de Juno

A maioria das consultas de juno contm pelo menos uma condio de juno, quer na
clusula FROM ou na clusula WHERE. A condio de juno compara duas colunas, cada uma
de uma tabela diferente. Para executar a juno, o Oracle Database combina pares de linhas,
cada uma contendo uma linha de cada tabela, para o qual a condio de juno deve ser
avaliada como TRUE. As colunas que participam nas condies no precisam aparecer na lista
de seleo.
Para executar uma juno de trs ou mais tabelas, o Oracle primeiramente junta duas das
tabelas com base nas condies de juno, comparando as suas colunas, e depois junta o
resultado com a outra tabela, com base nas condies de juno das colunas da outra tabela e
com as colunas do resultado. O Oracle continua este processo at que todas as tabelas
estejam associadas no resultado. O otimizador determina a ordem e junta as tabelas com base
nas condies de juno, nos ndices das tabelas e em todas as estatsticas disponveis para as
tabelas.
A clusula WHERE, que contm as condies de juno, tambm pode conter outras condies
que se referem s colunas das tabelas. Essas condies podem restringir ainda mais as linhas
retornadas pela consulta de juno.

Quando forem necessrios dados de mais de uma tabela na consulta, ser usada uma condio
de juno. As linhas de uma tabela podem ser unidas s linhas de outra tabela de acordo com
os valores comuns existentes nas colunas correspondentes, ou seja, em geral, colunas de
chave primria e chave estrangeira.
Para exibir dados de duas ou mais tabelas relacionadas, o usurio deve criar uma condio de
juno na clusula WHERE. A sintaxe da juno da Oracle :

SELECT tabela1.coluna, tabela2.coluna


FROM
tabela1, tabela2
WHERE tabela1.coluna1 = tabela2.coluna2;
Na sintaxe acima:

tabela1.coluna

denota a tabela e a coluna a partir das quais os dados so

recuperados.

tabela1.coluna1 = tabela2.coluna2 a condio que une (ou relaciona) tabelas


No exemplo abaixo:

SELECT employees.employee_id, employees.last_name,


employees.department_id, departments.department_id,
departments.location_id
FROM employees, departments
WHERE
employees.department_id=
departments.department_id;

A clusula SELECT especifica os nomes de colunas a serem

recuperados:
o

EMPLOYEE_ID, LAST_NAME, DEPARTMENT_ID, que so as

colunas contidas na tabela EMPLOYEES


4

DEPARTMENT_ID, DEPARTMENT_NAME e LOCATION_ID, que

so as colunas contidas na tabela DEPARTMENTS

A clusula FROM especifica as duas tabelas que o banco de dados deve


acessar:

tabela EMPLOYEES

tabela DEPARTMENTS

A clusula WHERE especifica como as tabelas sero unidas:

employees.department_id=departments.department_id

Como a coluna DEPARTMENT_ID comum s duas tabelas, ela deve ser precedida do nome da
tabela, a fim de evitar ambiguidade.
Qualificando Nomes de Colunas Ambguos
O usurio precisa qualificar os nomes das colunas na clusula WHERE com o nome da tabela, a
fim de evitar ambiguidade. Sem os prefixos de tabela, a coluna DEPARTMENT_ID pode ser
proveniente tanto da tabela DEPARTMENTS quanto da tabela EMPLOYEES. necessrio, ainda,
adicionar o prefixo de tabela para executar a consulta.
Se no houver nomes de colunas comuns s duas tabelas, no haver necessidade de qualificar
as colunas. No entanto, o uso do prefixo de tabela melhora o desempenho, pois informa ao
Oracle Server exatamente onde localizar as colunas.
A necessidade de qualificar nomes de colunas ambguos tambm se aplica s colunas que
possam ser ambguas em outras clusulas, como na clusula SELECT ou na clusula ORDER BY.
Condies de Pesquisa Adicionais
Alm da juno, possvel usar critrios para a clusula WHERE, a fim de restringir as linhas a
serem consideradas para uma ou mais tabelas da juno. Por exemplo, para exibir o nmero e
o nome do departamento do funcionrio Matos, necessria uma condio adicional na
clusula WHERE.

SELECT
last_name,
employees.department_id,
department_name
FROM employees, departments
WHERE
employees.department_id
=
departments.department_id
AND last_name = 'Matos';

1.3 Tipos de Junes


O banco de dados Oracle10g oferece sintaxe de juno que compatvel com SQL: 1999. Antes
da release 9i, a sintaxe de juno era diferente dos padres ANSI ("American National
Standards Institute"). A nova sintaxe de juno compatvel com SQL: 1999 no oferece
vantagens de desempenho em relao sintaxe da juno patenteada pela Oracle existente
nas releases anteriores.
Os tipos de junes patenteados pela Oracle so:

Equijuno;

No-equijuno;

Juno externa e,

Autojuno.

Os tipos de junes compatveis com o padro SQL: 1999 so:

Junes hbridas;

Junes naturais;

Clusula Using;

Junes externas de dois lados ou completas, e

Condies de juno arbitrrias para junes externas.

1.4 Equijunes

O relacionamento entre duas tabelas uma equijuno quando os valores nas colunas
utilizadas para juno so iguais. Geralmente, esse tipo de juno envolve colunas que sejam
chave primria e chave estrangeira. As equijunes tambm so denominadas junes simples
ou junes internas. Por exemplo:

SELECT d.department_name, e.first_name


FROM departments d, employees e
WHERE d.department_id = e.department_id;

1.5 No-equijunes

Uma no-equijuno uma condio de juno que no contm um operador de igualdade.


Por exemplo, o relacionamento entre a tabela EMPLOYEES e a tabela JOB_GRADES tem um
exemplo de no-equijuno. O relacionamento entre as duas tabelas baseia-se no fato de que
a coluna SALARY da tabela EMPLOYEES deve ter valores compreendidos entre os valores nas
colunas LOWEST_SALARY e HIGHEST_SALARY da tabela JOB_GRADES. Esse relacionamento
obtido atravs de um operador que no seja de igualdade (=).
EMPLOYEES

JOB_GRADES

Exemplo de consulta com no-equijuno:

SELECT e.last_name, e.salary, j.gra


FROM job_grades j, employees e
WHERE e.salary BETWEEN j.lowest_sal AND j.highest_sal;

Observa-se que todos


odos os funcionrios aparecem exatamente uma vez quando essa consulta
executada. Nenhum funcionrio repetido na lista. Nenhuma das linhas da tabela de
classificao
lassificao salarial possui classificaes que se sobrepem. Isto , o valor do salrio de um
funcionrio s pode estar compreendido entre os valores de menor e maior salrio de uma das
linhas da tabela de classificao salarial. Alm disso, todos os salrios
rios dos funcionrios esto
compreendidos entre os limites fornecidos pela tabela de classificao salarial. Nenhum
funcionrio recebe menos que o menor valor contido na coluna LOWEST_SAL nem mais que o
maior valor contido na coluna HIGHEST_SAL.
Outras condies,
dies, como <= e >=,
>= podem ser usadas, mas BETWEEN a mais simples. O usurio
deve se lembrar de especificar o menor valor primeiro e o maior valor depois quando estiver
usando BETWEEN.
Os apelidos de tabela foram especificados para melhorar o desempenho
desempenho e no devido a uma
possvel ambiguidade.

1.6 Junes Externas

Caso uma linha no atenda a uma condio de juno, ela no aparecer no resultado da
consulta. Por exemplo:

SELECT e.last_name, e.department_id, d.department_name


FROM employees e, departments d
WHERE e.department_id = d.department_id;

Na
condio
de
equijuno
das tabelas

EMPLOYEES e DEPARTMENTS, no h
funcionrios
os para o departamento 190
forma, esse departamento no aparecer
a
no resultado da juno.

e, dessa

As linhas ausentes podem ser retornadas se um operador de juno externa for usado na
condio de juno. O operador um sinal de mais entre parnteses (+) e colocado ao "lado"
da juno com informaes incompletas. Esse operador tem a funo de criar uma ou mais
linhas nulas, s quais podem ser unidas uma ou mais linhas da tabela completa.
Na sintaxe:

tabela1.coluna a condio que une (ou relaciona) as tabelas.

tabela2.coluna(+)

o smbolo de juno externa, que pode ser colocado

em qualquer lado da condio da clusula WHERE, mas no nos dois lados.


Deve-se
se colocar o smbolo de juno externa aps o nome da coluna na tabela sem as linhas
correspondentes.
Por exemplo, a consulta:

SELECT e.last_name, e.department_id,


e.department_id, d.department_name
FROM employees e, departments d
WHERE e.department_id(+) = d.department_id ;

Exibe
xibe os sobrenomes dos funcionrios, os IDs e os nomes de departamento. O departamento
de contratao (Contacting) no tem funcionrios e ento o valor em branco mostrado na
sada exibida.
9

O operador de juno externa s pode aparecer em um lado da expresso, o lado com


informaes incompletas. Ele retorna as linhas ausentes a partir de uma tabela que no possui
correspondncias diretas na outra tabela. Alm disso, uma condio envolvendo uma juno
externa no pode usar o operador IN nem pode estar vinculada a outra condio pelo
operador OR.

1.7 Autojunes

Autojuno permite a juno de uma tabela com ela mesma.. Por exemplo, para localizar o
nomee do gerente de cada funcionrio, necessrio unir a tabela EMPLOYEES a ela mesma ou
executar uma autojuno. Por exemplo:

SELECT ger.first_name, emp.first_name


FROM
OM employees ger, employees emp
WHERE ger.employee_id = emp.manager_id;
Essa consulta obtm, para cada funcionrio, o nome do funcionrio-gerente
funcionrio gerente cujo campo
manager_id de seu subordinado aponta. Isso faz com que o Oracle localize na mesma tabela o
nmero do gerente do trabalhador que corresponde a um nmero do funcionrio que
gerente.

1.8 Juno
no com a sintaxe da SQL 1999

Ao usar a sintaxe SQL 1999, podem-se


pode se obter os mesmos resultados mostrados nas pginas
anteriores com as junes patenteadas Oracle.
Oracle Na sintaxe:

tabela1.coluna: denota a tabela e a coluna a partir das quais os dados so


recuperados;
10

CROSS JOIN: retorna um produto cartesiano das duas tabelas;

NATURAL JOIN: une as duas tabelas com base no mesmo nome de coluna;

JOIN tabela USING nome_coluna: executa uma equijuno com base no


nome da coluna;

JOIN tabela ON tabela1.nome_coluna: executa uma equijuno com base na


condio da clusula ON.

LEFT/RIGHT/FULL OUTER: indica o tipo de juno externa

1.9 Junes Naturais

No Oracle10g, possvel deixar que a juno seja concluda automaticamente com base nas
colunas com nomes e tipos de dados correspondentes nas duas tabelas. Para isso, basta usar
as palavras-chave NATURAL JOIN. A juno s poder ocorrer nas colunas com os mesmos
nomes e tipos de dados nas duas tabelas. Se as colunas tiverem o mesmo nome, mas tipos de
dados diferentes, a sintaxe NATURAL JOIN ocasionar um erro.
Exemplo da juno natural:

SELECT department_id, department_name, location_id, city


FROM
departments
NATURAL JOIN locations ;
Nesse exemplo, a tabela LOCATIONS unida tabela DEPARTMENT por meio da coluna
LOCATION_ID, que a nica com o mesmo nome nas duas tabelas. Se outras colunas em
comum estivessem presentes, a juno teria usado todas elas.

A juno natural tambm pode ser expressa como uma equijuno:

SELECT department_id, department_name, departments.location_id


FROM departments, locations
WHERE departments.location_id = locations.location_id;

As restries adicionais em uma juno natural so implementadas por meio de uma clusula
WHERE. Conforme pode ser observado, a consulta restringe as linhas da sada que tem um ID
de departamento igual a 20 ou 50.
11

SELECT department_id, department_name, location_id, city


FROM departments
NATURAL JOIN locations
WHERE department_id IN (20, 50);
1.10 Clusula Using

As junes naturais, conforme visto anteriormente, usam todas as colunas com nomes e tipos
de dados correspondentes para unir as tabelas. A clusula USING pode ser utilizada para
especificar apenas as colunas que devem ser usadas em uma equijuno. As colunas s quais a
clusula USING faz referncia no devem ter um qualificador (apelido ou nome de tabela) em
nenhuma parte da instruo SQL.
Por exemplo, essa instruo vlida:

SELECT l.city, d.department_name


FROM
locations l JOIN departments d USING (location_id)
WHERE location_id = 1400;
Por outro lado, a instruo a seguir invlida porque a coluna LOCATION_ID aparece com um
qualificador na clusula WHERE:

SELECT l.city, d.department_name


FROM locations l JOIN departments d USING (location_id)
WHERE d.location_id = 1400;
O erro provocado pela instruo invlida ORA-25154: column part of USING clause cannot
have qualifier.
A mesma restrio se aplica s junes do tipo NATURAL. Assim, colunas com o mesmo nome
nas duas tabelas devem ser usadas sem qualificador.

1.11 Clusula ON

A clusula ON deve ser utilizada para especificar uma condio de juno. Isso permite que o
usurio especifique condies de juno separadas de qualquer condio de pesquisa ou de
filtro na clusula WHERE. Isso permite que a condio de juno seja separada de outras

condies de pesquisa. Dessa forma, pode-se dizer que a clusula ON facilita a compreenso
do cdigo. Por exemplo:
12

SELECT e.employee_id, e.last_name, e.department_id,


d.location_id
FROM employees e JOIN departments d
ON (e.department_id = d.department_id) ;

d.department_id,

A clusula ON tambm pode ser usada para autojuno, ou seja, juno de uma tabela com ela
mesma quando as colunas possuem nomes diferentes:

SELECT e.last_name emp, m.last_name mgr


FROM employees e JOIN employees m
ON (e.manager_id = m.employee_id);

A clusula ON tambm pode ser utilizada em uma juno tripla. Uma juno tripla consiste de
uma juno que une trs tabelas. Na sintaxe compatvel com SQL: 1999, as junes so
efetuadas da esquerda para a direita; sendo assim, a primeira juno a ser feita EMPLOYEES
JOIN DEPARTMENTS.

SELECT employee_id, city, department_name


FROM employees e
JOIN departments d
ON d.department_id = e.department_id
JOIN locations l
ON d.location_id = l.location_id;

13

A primeira condio de juno pode fazer referncia a colunas nas tabelas EMPLOYEES e
DEPARTMENTS, mas no a colunas na tabela LOCATIONS. A segunda condio de juno pode
fazer referncia a colunas de todas as trs tabelas.
Esse tipo de consulta tambm pode ser expresso como uma equijuno tripla:

SELECT employee_id, city, department_name


FROM employees, departments, locations
WHERE employees.department_id =departments.department_id
AND departments.location_id = locations.location_id;

14