13
Exibição de Dados de Várias Tabelas PARTE I Conteudista Prof. Me. MARCUS ROGERIO OLIVEIRA

Exibicao de Dados de Varias Tabelas PARTE I

Embed Size (px)

DESCRIPTION

oracle

Citation preview

Exibição de Dados de Várias Tabelas PARTE I

Conteudista

Prof. Me. MARCUS ROGERIO OLIVEIRA

3

SQL FUNDAMENTALS I E PROGRAM WITH

PL/SQL

1 Unidade 2 - Exibição de Dados de Várias Tabelas

1.1 Conceitos Básicos

A junção (join) é uma consulta que combina linhas de duas ou mais tabelas, views ou views

materializadas. O Oracle Database realiza uma junção sempre que múltiplas tabelas aparecem

na cláusula FROM da consulta. A lista de seleção da consulta pode selecionar todas as colunas

de qualquer uma dessas tabelas. Se duas dessas tabelas têm um nome de coluna em comum,

então o usuário deve qualificar todas as referências a essas colunas em toda a consulta com o

nome da respectiva tabela, para evitar ambiguidade.

1.2 Condições de Junção

A maioria das consultas de junção contém pelo menos uma condição de junção, quer na

cláusula FROM ou na cláusula WHERE. A condição de junção compara duas colunas, cada uma

de uma tabela diferente. Para executar a junção, o Oracle Database combina pares de linhas,

cada uma contendo uma linha de cada tabela, para o qual a condição de junção deve ser

avaliada como TRUE. As colunas que participam nas condições não precisam aparecer na lista

de seleção.

Para executar uma junção de três ou mais tabelas, o Oracle primeiramente junta duas das

tabelas com base nas condições de junção, comparando as suas colunas, e depois junta o

resultado com a outra tabela, com base nas condições de junção 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 condições de junção, nos índices das tabelas e em todas as estatísticas disponíveis para as

tabelas.

A cláusula WHERE, que contém as condições de junção, também pode conter outras condições

que se referem às colunas das tabelas. Essas condições podem restringir ainda mais as linhas

retornadas pela consulta de junção.

4

Quando forem necessários dados de mais de uma tabela na consulta, será usada uma condição

de junção. 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 primária e chave estrangeira.

Para exibir dados de duas ou mais tabelas relacionadas, o usuário deve criar uma condição de

junção na cláusula WHERE. A sintaxe da junção 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 são

recuperados.

• “tabela1.coluna1 = tabela2.coluna2” é a condição 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 cláusula SELECT especifica os nomes de colunas a serem

recuperados:

o EMPLOYEE_ID, LAST_NAME, DEPARTMENT_ID, que são as

colunas contidas na tabela EMPLOYEES

5

o DEPARTMENT_ID, DEPARTMENT_NAME e LOCATION_ID, que

são as colunas contidas na tabela DEPARTMENTS

• A cláusula FROM especifica as duas tabelas que o banco de dados deve

acessar:

o tabela EMPLOYEES

o tabela DEPARTMENTS

• A cláusula WHERE especifica como as tabelas serão 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 Ambíguos

O usuário precisa qualificar os nomes das colunas na cláusula 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. É necessário, ainda,

adicionar o prefixo de tabela para executar a consulta.

Se não houver nomes de colunas comuns às duas tabelas, não 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 ambíguos também se aplica às colunas que

possam ser ambíguas em outras cláusulas, como na cláusula SELECT ou na cláusula ORDER BY.

Condições de Pesquisa Adicionais

Além da junção, é possível usar critérios para a cláusula WHERE, a fim de restringir as linhas a

serem consideradas para uma ou mais tabelas da junção. Por exemplo, para exibir o número e

o nome do departamento do funcionário Matos, é necessária uma condição adicional na

cláusula WHERE.

SELECT last_name, employees.department_id, department_name

FROM employees, departments WHERE employees.department_id =

departments.department_id AND last_name = 'Matos';

6

1.3 Tipos de Junções

O banco de dados Oracle10g oferece sintaxe de junção que é compatível com SQL: 1999. Antes

da release 9i, a sintaxe de junção era diferente dos padrões ANSI ("American National

Standards Institute"). A nova sintaxe de junção compatível com SQL: 1999 não oferece

vantagens de desempenho em relação à sintaxe da junção patenteada pela Oracle existente

nas releases anteriores.

Os tipos de junções patenteados pela Oracle são:

• Equijunção;

• Não-equijunção;

• Junção externa e,

• Autojunção.

Os tipos de junções compatíveis com o padrão SQL: 1999 são:

• Junções híbridas;

• Junções naturais;

• Cláusula Using;

• Junções externas de dois lados ou completas, e

• Condições de junção arbitrárias para junções externas.

1.4 Equijunções

O relacionamento entre duas tabelas é uma equijunção – quando os valores nas colunas

utilizadas para junção são iguais. Geralmente, esse tipo de junção envolve colunas que sejam

chave primária e chave estrangeira. As equijunções também são denominadas junções simples

ou junções internas. Por exemplo:

SELECT d.department_name, e.first_name FROM departments d, employees e WHERE d.department_id = e.department_id;

7

1.5 Não-equijunções

Uma não-equijunção é uma condição de junção que não contém um operador de igualdade.

Por exemplo, o relacionamento entre a tabela EMPLOYEES e a tabela JOB_GRADES tem um

exemplo de não-equijunção. 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 através de um operador que não seja de igualdade (=).

Exemplo de consulta com não-equijunção:

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;

JOB_GRADES EMPLOYEES

Observa-se que todos os funcionários aparecem exatamente uma vez quando essa consulta é

executada. Nenhum funcionário é repetido na lista. Nenhuma das linhas da tabela de

classificação salarial possui classificações que se sobrepõem. Isto é, o valor do salário de um

funcionário só pode estar compreendido entre os valores de menor e maior salário de uma das

linhas da tabela de classificação salarial.

compreendidos entre os limites fornecidos pela tabela de classificação salarial.

funcionário recebe menos que o menor valor contido na coluna LOWEST_SAL nem mais que o

maior valor contido na coluna HIGHEST_SAL.

Outras condições, como <= e >=

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 desempenh

possível ambiguidade.

1.6 Junções Externas

Caso uma linha não atenda a

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;

EMPLOYEES e DEPARTMENTS,

funcionários para o departamento 190

forma, esse departamento não a

8

odos os funcionários aparecem exatamente uma vez quando essa consulta é

executada. Nenhum funcionário é repetido na lista. Nenhuma das linhas da tabela de

lassificação salarial possui classificações que se sobrepõem. Isto é, o valor do salário de um

funcionário só pode estar compreendido entre os valores de menor e maior salário de uma das

linhas da tabela de classificação salarial. Além disso, todos os salários dos funcionários estão

compreendidos entre os limites fornecidos pela tabela de classificação salarial.

funcionário recebe menos que o menor valor contido na coluna LOWEST_SAL nem mais que o

maior valor contido na coluna HIGHEST_SAL.

dições, como <= e >=, podem ser usadas, mas BETWEEN é a mais simples.

de especificar o menor valor primeiro e o maior valor depois quando estiver

Os apelidos de tabela foram especificados para melhorar o desempenho e não devido a uma

a uma condição de junção, ela não aparecerá no resultado da

SELECT e.last_name, e.department_id, d.department_name FROM employees e, departments d WHERE e.department_id = d.department_id;

EMPLOYEES e DEPARTMENTS, não há

os para o departamento 190

forma, esse departamento não aparecerá no resultado da junção.

odos os funcionários aparecem exatamente uma vez quando essa consulta é

executada. Nenhum funcionário é repetido na lista. Nenhuma das linhas da tabela de

lassificação salarial possui classificações que se sobrepõem. Isto é, o valor do salário de um

funcionário só pode estar compreendido entre os valores de menor e maior salário de uma das

rios dos funcionários estão

compreendidos entre os limites fornecidos pela tabela de classificação salarial. Nenhum

funcionário recebe menos que o menor valor contido na coluna LOWEST_SAL nem mais que o

podem ser usadas, mas BETWEEN é a mais simples. O usuário

de especificar o menor valor primeiro e o maior valor depois quando estiver

o e não devido a uma

uma condição de junção, ela não aparecerá no resultado da

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

Na

condição

de

equijunção

das tabelas

e, dessa

As linhas ausentes podem ser retornadas se um operador de junção externa for usado na

condição de junção. O operador é um sinal de mais entre parênteses (+) e é colocado ao "lado"

da junção com informações incompletas. Esse

linhas nulas, às quais podem ser unidas uma ou mais linhas da tabela completa.

Na sintaxe:

• tabela1.coluna é a condição que une (ou relaciona) as tabelas.

• tabela2.coluna(+)

em qualquer lado da condição da cláusula WHERE, mas não nos dois lados.

Deve-se colocar o símbolo de junção externa após o nome da coluna na tabela sem as linhas

correspondentes.

Por exemplo, a consulta:

SELECT e.last_name, e.departmentFROM employees e, departments d WHERE e.department_id(+) = d.department_id ;

Exibe os sobrenomes dos funcionários, os IDs e os nomes de departamento. O departamento

de contratação (Contacting) não tem funcionários

saída exibida.

9

As linhas ausentes podem ser retornadas se um operador de junção externa for usado na

condição de junção. O operador é um sinal de mais entre parênteses (+) e é colocado ao "lado"

da junção com informações incompletas. Esse operador tem a função de criar uma ou mais

linhas nulas, às quais podem ser unidas uma ou mais linhas da tabela completa.

tabela1.coluna é a condição que une (ou relaciona) as tabelas.

tabela2.coluna(+) é o símbolo de junção externa, que pode ser colocado

em qualquer lado da condição da cláusula WHERE, mas não nos dois lados.

se colocar o símbolo de junção externa após o nome da coluna na tabela sem as linhas

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

xibe os sobrenomes dos funcionários, os IDs e os nomes de departamento. O departamento

não tem funcionários e então o valor em branco é mostrado na

As linhas ausentes podem ser retornadas se um operador de junção externa for usado na

condição de junção. O operador é um sinal de mais entre parênteses (+) e é colocado ao "lado"

operador tem a função de criar uma ou mais

linhas nulas, às quais podem ser unidas uma ou mais linhas da tabela completa.

tabela1.coluna é a condição que une (ou relaciona) as tabelas.

pode ser colocado

em qualquer lado da condição da cláusula WHERE, mas não nos dois lados.

se colocar o símbolo de junção externa após o nome da coluna na tabela sem as linhas

_id, d.department_name

xibe os sobrenomes dos funcionários, os IDs e os nomes de departamento. O departamento

valor em branco é mostrado na

O operador de junção externa só pode aparecer em um lado da expressão, o lado com

informações incompletas. Ele retorna as linhas ausentes a partir de uma tabela que não possui

correspondências diretas na outra

externa não pode usar o operador IN nem pode estar vinculada a outra condição pelo

operador OR.

1.7 Autojunções

Autojunção permite a junção de uma

nome do gerente de cada funcionário, é necessário unir a tabela EMPLOYEES a ela mesma ou

executar uma autojunção. Por exemplo:

SELECT ger.first_name, emp.first_nameFROM employees ger, employees empWHERE ger.employee_id = emp.manager_id;

Essa consulta obtém, para cada funcionário, o nome do funcionário

manager_id de seu subordinado aponta.

número do gerente do trabalhador

gerente.

1.8 Junção com a sintaxe da SQL 1999

Ao usar a sintaxe SQL 1999, pode

anteriores com as junções patenteadas Oracle

• tabela1.coluna: denota a tabela e a coluna a partir das quais os dados são

recuperados;

10

O operador de junção externa só pode aparecer em um lado da expressão, o lado com

informações incompletas. Ele retorna as linhas ausentes a partir de uma tabela que não possui

correspondências diretas na outra tabela. Além disso, uma condição envolvendo uma junção

externa não pode usar o operador IN nem pode estar vinculada a outra condição pelo

Autojunção permite a junção de uma tabela com ela mesma. Por exemplo, para localizar o

e do gerente de cada funcionário, é necessário unir a tabela EMPLOYEES a ela mesma ou

Por exemplo:

SELECT ger.first_name, emp.first_name OM employees ger, employees emp

WHERE ger.employee_id = emp.manager_id;

obtém, para cada funcionário, o nome do funcionário-gerente cujo campo

manager_id de seu subordinado aponta. Isso faz com que o Oracle localize na mesma tabela

número do gerente do trabalhador que corresponde a um número do funcionário

nção com a sintaxe da SQL 1999

Ao usar a sintaxe SQL 1999, podem-se obter os mesmos resultados mostrados nas páginas

com as junções patenteadas Oracle. Na sintaxe:

tabela1.coluna: denota a tabela e a coluna a partir das quais os dados são

recuperados;

O operador de junção externa só pode aparecer em um lado da expressão, o lado com

informações incompletas. Ele retorna as linhas ausentes a partir de uma tabela que não possui

tabela. Além disso, uma condição envolvendo uma junção

externa não pode usar o operador IN nem pode estar vinculada a outra condição pelo

. Por exemplo, para localizar o

e do gerente de cada funcionário, é necessário unir a tabela EMPLOYEES a ela mesma ou

gerente cujo campo

faz com que o Oracle localize na mesma tabela o

número do funcionário que é

se obter os mesmos resultados mostrados nas páginas

tabela1.coluna: denota a tabela e a coluna a partir das quais os dados são

11

• 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 equijunção com base no

nome da coluna;

• JOIN tabela ON tabela1.nome_coluna: executa uma equijunção com base na

condição da cláusula ON.

• LEFT/RIGHT/FULL OUTER: indica o tipo de junção externa

1.9 Junções Naturais

No Oracle10g, é possível deixar que a junção seja concluída 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 junção 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 junção 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 junção teria usado todas elas.

A junção natural também pode ser expressa como uma equijunção:

SELECT department_id, department_name, departments.location_id FROM departments, locations WHERE departments.location_id = locations.location_id;

As restrições adicionais em uma junção natural são implementadas por meio de uma cláusula

WHERE. Conforme pode ser observado, a consulta restringe as linhas da saída que tem um ID

de departamento igual a 20 ou 50.

12

SELECT department_id, department_name, location_id, city FROM departments NATURAL JOIN locations WHERE department_id IN (20, 50);

1.10 Cláusula Using

As junções naturais, conforme visto anteriormente, usam todas as colunas com nomes e tipos

de dados correspondentes para unir as tabelas. A cláusula USING pode ser utilizada para

especificar apenas as colunas que devem ser usadas em uma equijunção. As colunas às quais a

cláusula USING faz referência não devem ter um qualificador (apelido ou nome de tabela) em

nenhuma parte da instrução SQL.

Por exemplo, essa instrução é válida:

SELECT l.city, d.department_name FROM locations l JOIN departments d USING (location_id) WHERE location_id = 1400;

Por outro lado, a instrução a seguir é inválida porque a coluna LOCATION_ID aparece com um

qualificador na cláusula 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 instrução inválida é “ORA-25154: column part of USING clause cannot

have qualifier”.

A mesma restrição se aplica às junções do tipo NATURAL. Assim, colunas com o mesmo nome

nas duas tabelas devem ser usadas sem qualificador.

1.11 Cláusula ON

A cláusula ON deve ser utilizada para especificar uma condição de junção. Isso permite que o

usuário especifique condições de junção separadas de qualquer condição de pesquisa ou de

filtro na cláusula WHERE. Isso permite que a condição de junção seja separada de outras

condições de pesquisa. Dessa forma, pode-se dizer que a cláusula ON facilita a compreensão

do código. Por exemplo:

13

SELECT e.employee_id, e.last_name, e.department_id, d.department_id, d.location_id FROM employees e JOIN departments d ON (e.department_id = d.department_id) ;

A cláusula ON também pode ser usada para autojunção, ou seja, junção 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 cláusula ON também pode ser utilizada em uma junção tripla. Uma junção tripla consiste de

uma junção que une três tabelas. Na sintaxe compatível com SQL: 1999, as junções são

efetuadas da esquerda para a direita; sendo assim, a primeira junção 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;

14

A primeira condição de junção pode fazer referência a colunas nas tabelas EMPLOYEES e

DEPARTMENTS, mas não a colunas na tabela LOCATIONS. A segunda condição de junção pode

fazer referência a colunas de todas as três tabelas.

Esse tipo de consulta também pode ser expresso como uma equijunção 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;